• Jump To … +
    AJAXCompleter.js AJAXEmailClientCompleter.js AJAXOtherCompleter.js AJAXReferenceChoice.js AJAXReferenceCompleter.js AJAXReferenceCompleterMulti.js AJAXReferenceControls.js AJAXTableCompleter.js AttachmentUploader.js AutoComplete.js BoundsUtil2.js CookieJar.js CustomEventManager.js DaysOfWeekElement.js DerivedFields.js Draggable2.js DropTarget2.js FieldListElement.js GlideAPI1.js GlideAjax.js GlideAjaxForm.js GlideBox.js GlideClientCache.js GlideDecoration.js GlideDialogForm.js GlideDialogWindow.js GlideDraggable.js GlideDuration.js GlideEvent.js GlideEventHandler.js GlideFilter14.js GlideFilterDate.js GlideFilterDescription.js GlideFilterHandlers.js GlideFilterItemVariables.js GlideFilterLabels.js GlideFilterQuestions.js GlideFilterReference.js GlideFilterReferenceMulti.js GlideFilterVariables.js GlideForm14.js GlideHeaderSearch.js GlideList2.js GlideList2FilterUtil.js GlideList2Handlers.js GlideList2InitEvents.js GlideList2Statics.js GlideListAggregates.js GlideListEditor.js GlideListEditorMessaging.js GlideListElement.js GlideListWidget.js GlideListv3Compatibility.js GlideModal.js GlideModalForm.js GlideNavigation.js GlideOverlay.js GlidePane.js GlidePaneForm.js GlideRecord.js GlideTabs2.js GlideTabs2State.js GlideTabs2Tab.js GlideTimeElement.js GlideTimerElement.js GlideTransactionScope.js GlideUI.js GlideUIDefault.js GlideUIElement.js GlideUINotification.js GlideURL.js GlideURLElement.js GlideUser.js GlideUserImageElement.js GlideWidgetActions.js GlideWidgetFilter.js GlideWidgetHideOnEmpty.js GlideWidgetSearch.js GlideWidgetVCR.js GlideWindow.js GuidedTourElementTranslator.js GwtCellEditor.js GwtCellSelector.js GwtContextMenu.js GwtCursor.js GwtDate.js GwtDraggable.js GwtDraggableSnap.js GwtExportScheduleDialog.js GwtGridEdit.js GwtListEditAjaxChangeSaver.js GwtListEditAjaxValueLoader.js GwtListEditBoolean.js GwtListEditCalendar.js GwtListEditDependent.js GwtListEditDuration.js GwtListEditEncryptedText.js GwtListEditError.js GwtListEditGList.js GwtListEditGlideRecord.js GwtListEditGridSelector.js GwtListEditInternalType.js GwtListEditJournal.js GwtListEditMultiText.js GwtListEditPassword.js GwtListEditRecord.js GwtListEditRecordDecorations.js GwtListEditReference.js GwtListEditRelatedTags.js GwtListEditSavePolicy.js GwtListEditSelect.js GwtListEditTableController.js GwtListEditTablename.js GwtListEditText.js GwtListEditTranslatedField.js GwtListEditUpdateTablename.js GwtListEditValueRenderer.js GwtListEditWindow.js GwtListEditor.js GwtListEditorPendingChanges.js GwtMessage14.js GwtObservable.js GwtPollDialog.js InPlaceEdit.js LAB.min.js ListDraggableRow2.js ListSelectManager2.js ListSortDual2.js ListSortWindow2.js NOW.messaging.js NOW.messaging.record.js NameMapEntry.js NotificationMessage.js PageTiming14.js PersonalizeForm.js Point.js SLARepairClient.js ScriptLoader.js Select.js SlushBucket.js SortDraggable2.js SortDropTarget2.js SortListManager2.js SortUtil2.js StopWatch.js Table.js TableElement.js TableExtension.js TemplateRecord.js TextAreaElement.js UserRolesElement.js UtilityAndOverrides2.js _module.js ac.js ac_derived_field_support.js accessibility_tabindex.js affix.js alert.js amb.Channel.js amb.ChannelListener.js amb.ChannelRedirect.js amb.EventManager.js amb.Logger.js amb.MessageClient.js amb.MessageClientBuilder.js amb.ServerConnection.js amb_initialize.js amb_properties.js angular-animate.js angular-aria.js angular-cookies.js angular-file-upload-all.js angular-resource.js angular-route.js angular-sanitize.js angular-tooltips.min.js angular-touch.js angular-ui-tinymce.js angular.js angular_includes_no_min_1.5.3.js annotations_toggle.js app.$sp.js app.config.js app.form_presence.js app.ng.amb.js app_guided_tours.js attachments.js bootstrap-datetimepicker.js bootstrap-iconpicker.js bootstrap_336.js button.js cabrillo.factory.js calendar.js camera.js carousel.js catalogDataLookup.js catalogGlideFormFactory.js catalogItemFactory.js clientScript_components.js collapse.js cometd.js condition14_new.js condition14_reporting.js condition14_templates.js condition_global_variables14.js constants_embedded_help.js context_actions.js controller.AMBRecordWatcher.js controller.Stream.js controller.formStream.js controller.guidedTours.js controller.spLogin.js controller.spPage.js controller.spWidgetDebug.js core.js debug.js decorator.uiTinymce.js deferred_related_lists.js depends.js directive.contenteditable.js directive.glideFormField.js directive.glyph.js directive.message.js directive.nowAttachmentsList.js directive.recursiveHelper.js directive.scroll_form.js directive.snAttachmentList.js directive.snAttachmentPreview.js directive.snAvatar.js directive.snAvatarPopover.js directive.snBindI18n.js directive.snBindOnce.js directive.snBindPopoverSelection.js directive.snBlurOnEnter.js directive.snChoiceList.js directive.snCloak.js directive.snComplexPopover.js directive.snConfirmModal.js directive.snContextMenu.js directive.snDayAgo.js directive.snDialog.js directive.snExpandedEmail.js directive.snFieldReference.js directive.snFileUploadInput.js directive.snFlyout.js directive.snFocus.js directive.snGlyph.js directive.snImageUploader.js directive.snLinkContent.js directive.snLinkContentArticle.js directive.snLinkContentAttachment.js directive.snLinkContentError.js directive.snLinkContentImage.js directive.snLinkContentRecord.js directive.snLinkContentSoundcloud.js directive.snLinkContentYoutube.js directive.snMentionPopover.js directive.snModal.js directive.snModalShow.js directive.snNotification.js directive.snPasteImageHandler.js directive.snPresence.js directive.snRecordPicker.js directive.snReferencePicker.js directive.snResizeHeight.js directive.snSelectBasic.js directive.snStickyHeaders.js directive.snStream.js directive.snSyncWith.js directive.snTableReference.js directive.snTabs.js directive.snTextExpander.js directive.snTimeAgo.js directive.snUserAvatar.js directive.snUserProfile.js directive.spAttachmentButton.js directive.spCLink.js directive.spCatItem.js directive.spChoiceList.js directive.spCodeMirror.js directive.spColorPicker.js directive.spContextMenu.js directive.spCssEditor.js directive.spCurrencyElement.js directive.spDatePicker.js directive.spDropdownTree.js directive.spDurationElement.js directive.spEditableField.js directive.spFieldListElement.js directive.spFormField.js directive.spGlyph.js directive.spGlyphPicker.js directive.spHTMLEditor.js directive.spHtmlContent.js directive.spMessageDialog.js directive.spModel.js directive.spNavbarToggle.js directive.spNotifications.js directive.spOnTransition.js directive.spPageRow.js directive.spPanel.js directive.spReferenceElement.js directive.spReferenceField.js directive.spScriptEditor.js directive.spTinymceEditor.js directive.spWidget.js dropdown.js dropdowns.js email_activity.js event_initialize.js factory.AMBOverlay.js factory.ArraySynchronizer.js factory.glideUrlBuilder.js factory.notificationWrapper.js factory.nowAttachmentHandler.js factory.paneManager.js factory.snAttachmentHandler.js factory.snPresence.js factory.snRecordPresence.js factory.snRecordWatcher.js factory.spInterceptor.js factory.spMacro.js factory.spServer.js factory.spUIActionFactory.js factory.spWidget.js factory.unwrappedHTTPPromise.js filter.spTruncate.js fixedHeaders.js floating_scrollbar.min.js form.js form_submitted_mask.js form_tags.js formatting.js functions.js functions_attachments.js functions_bootstrap14.js functions_calendar.js functions_clipboard.js functions_email.js functions_fontsizer.js functions_onchange.js functions_reference.js functions_showloading.js functions_user_image.js geolocation.js glideAjaxFactory.js glideFormEnvironmentFactory.js glideFormFactory.js glideFormFieldFactory.js glideFormMessageHandler.js glideListFactory.js glideModalFactory.js glideRecordData.js glideRecordFactory.js glideRequest.js glideUIActionsFactory.js glideUserFactory.js glideUserSession.js guided_tours_template.js heisenberg_all.js html_class_setter.js iconset-fontawesome-4.2.0.js jQueryRequestShim.js jquery-1.11.0.min.js jquery-1.11.0_no_conflict.js jquery-1.8.2.min.js jquery-2.1.js jquery-ui-1.9.2.custom.js jquery.cometd.js jquery_clean.js jquery_includes.js jquery_no_conflict.js js_guided_tours_includes.js js_includes_amb.js js_includes_angular.js js_includes_attachments.js js_includes_avatar.js js_includes_cabrillo.js js_includes_clientScript.js js_includes_common.js js_includes_controls.js js_includes_customer.js js_includes_data.js js_includes_datetime.js js_includes_doctype.js js_includes_form.js js_includes_form_presence.js js_includes_glide.js js_includes_i18n.js js_includes_last_doctype.js js_includes_link.js js_includes_list_edit_doctype.js js_includes_listv2_doctype.js js_includes_mention.js js_includes_messaging.js js_includes_ng_amb.js js_includes_notification.js js_includes_presence.js js_includes_sorting_new.js js_includes_sp.js js_includes_sp_core.js js_includes_sp_deps.js js_includes_sp_tinymce.js js_includes_stream.js js_includes_ui.js js_includes_ui_popover.js js_includes_user_profile.js js_includes_util.js list.js list_filter.js lodash.min.js magellan.CreateFavoriteModal.js mentio.js modal.js modals.js moment-2.8.3.js navigation.js newtag-it.js ng-sortable.js ocLazyLoad.min.js page_title.js popover.js popovers.js popupdivs14.js popups.js prism.js prototype.effects.js prototype.hidefix.js prototype.js prototype.min.js prototype.plugin.js prototype.template.js provider.defaultJSAutocomplete.js provider.lazyloader.js provider.linkContentTypes.js scoped_object_generators.js scrollable.js scrollspy.js section.js select2.js select2.min.js selects.js service.AMB.js service.authInterceptor.js service.avatarProfilePersister.js service.dateUtils.js service.debounceFn.js service.filterExpressionParser.js service.getTemplateUrl.js service.guidedToursService.js service.i18n.js service.md5.js service.nowServer.js service.nowStream.js service.priorityQueue.js service.progressDialog.js service.queryFilter.js service.snComplexPopoverService.js service.snConnect.js service.snCustomEvent.js service.snMention.js service.snNotification.js service.snNotifier.js service.snResource.js service.snTabActivity.js service.spCodeEditorAutocomplete.js service.spCommunicator.js service.spFileSelect.js service.spIs.js service.spModal.js service.spPreference.js service.spThrottle.js service.spUtil.js service.urlTools.js service.userData.js service.userPreferences.js simpleStorage.js snPolyfill.js snPopover.js snTimeAgoSettings.js snm.auth.data.module.js snm.serviceCatalog.data.shim.js snm.serviceCatalog.form.module.js sortable.min.js sp.geo.js streamButton.js tables.js tabs.js tabs2_14.js templates.js textutil.js theme.min.js timeAgo.js tinymce.min.js tooltip.js tooltips.js transaction_scope_includes.js transition.js ui-bootstrap-tpls-1.1.2.js uiPolicyFactory.js uiPolicyTypes.js ui_policy.js utils14.js viewLayout.js xmlUtil.js xmlhttp.js z_last_include.js
  • js_includes_sp.js

  • ¶
    /*! RESOURCE: /scripts/js_includes_sp.js */
    /*! RESOURCE: /scripts/js_includes_sp_deps.js */
    /*! RESOURCE: /scripts/lib/jquery/jquery-2.1.js */
    (function(global, factory) {
        if (typeof module === "object" && typeof module.exports === "object") {
            module.exports = global.document ?
                factory(global, true) :
                function(w) {
                    if (!w.document) {
                        throw new Error("jQuery requires a window with a document");
                    }
                    return factory(w);
                };
        } else {
            factory(global);
        }
    }(typeof window !== "undefined" ? window : this, function(window, noGlobal) {
        var arr = [];
        var slice = arr.slice;
        var concat = arr.concat;
        var push = arr.push;
        var indexOf = arr.indexOf;
        var class2type = {};
        var toString = class2type.toString;
        var hasOwn = class2type.hasOwnProperty;
        var support = {};
        var
            document = window.document,
            version = "2.1.4",
            jQuery = function(selector, context) {
                return new jQuery.fn.init(selector, context);
            },
            rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
            rmsPrefix = /^-ms-/,
            rdashAlpha = /-([\da-z])/gi,
            fcamelCase = function(all, letter) {
                return letter.toUpperCase();
            };
        jQuery.fn = jQuery.prototype = {
            jquery: version,
            constructor: jQuery,
            selector: "",
            length: 0,
            toArray: function() {
                return slice.call(this);
            },
            get: function(num) {
                return num != null ?
                    (num < 0 ? this[num + this.length] : this[num]) :
                    slice.call(this);
            },
            pushStack: function(elems) {
                var ret = jQuery.merge(this.constructor(), elems);
                ret.prevObject = this;
                ret.context = this.context;
                return ret;
            },
            each: function(callback, args) {
                return jQuery.each(this, callback, args);
            },
            map: function(callback) {
                return this.pushStack(jQuery.map(this, function(elem, i) {
                    return callback.call(elem, i, elem);
                }));
            },
            slice: function() {
                return this.pushStack(slice.apply(this, arguments));
            },
            first: function() {
                return this.eq(0);
            },
            last: function() {
                return this.eq(-1);
            },
            eq: function(i) {
                var len = this.length,
                    j = +i + (i < 0 ? len : 0);
                return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
            },
            end: function() {
                return this.prevObject || this.constructor(null);
            },
            push: push,
            sort: arr.sort,
            splice: arr.splice
        };
        jQuery.extend = jQuery.fn.extend = function() {
            var options, name, src, copy, copyIsArray, clone,
                target = arguments[0] || {},
                i = 1,
                length = arguments.length,
                deep = false;
            if (typeof target === "boolean") {
                deep = target;
                target = arguments[i] || {};
                i++;
            }
            if (typeof target !== "object" && !jQuery.isFunction(target)) {
                target = {};
            }
            if (i === length) {
                target = this;
                i--;
            }
            for (; i < length; i++) {
                if ((options = arguments[i]) != null) {
                    for (name in options) {
                        src = target[name];
                        copy = options[name];
                        if (target === copy) {
                            continue;
                        }
                        if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {
                            if (copyIsArray) {
                                copyIsArray = false;
                                clone = src && jQuery.isArray(src) ? src : [];
                            } else {
                                clone = src && jQuery.isPlainObject(src) ? src : {};
                            }
                            target[name] = jQuery.extend(deep, clone, copy);
                        } else if (copy !== undefined) {
                            target[name] = copy;
                        }
                    }
                }
            }
            return target;
        };
        jQuery.extend({
            expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""),
            isReady: true,
            error: function(msg) {
                throw new Error(msg);
            },
            noop: function() {},
            isFunction: function(obj) {
                return jQuery.type(obj) === "function";
            },
            isArray: Array.isArray,
            isWindow: function(obj) {
                return obj != null && obj === obj.window;
            },
            isNumeric: function(obj) {
                return !jQuery.isArray(obj) && (obj - parseFloat(obj) + 1) >= 0;
            },
            isPlainObject: function(obj) {
                if (jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow(obj)) {
                    return false;
                }
                if (obj.constructor &&
                    !hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
                    return false;
                }
                return true;
            },
            isEmptyObject: function(obj) {
                var name;
                for (name in obj) {
                    return false;
                }
                return true;
            },
            type: function(obj) {
                if (obj == null) {
                    return obj + "";
                }
                return typeof obj === "object" || typeof obj === "function" ?
                    class2type[toString.call(obj)] || "object" :
                    typeof obj;
            },
            globalEval: function(code) {
                var script,
                    indirect = eval;
                code = jQuery.trim(code);
                if (code) {
                    if (code.indexOf("use strict") === 1) {
                        script = document.createElement("script");
                        script.text = code;
                        document.head.appendChild(script).parentNode.removeChild(script);
                    } else {
                        indirect(code);
                    }
                }
            },
            camelCase: function(string) {
                return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase);
            },
            nodeName: function(elem, name) {
                return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
            },
            each: function(obj, callback, args) {
                var value,
                    i = 0,
                    length = obj.length,
                    isArray = isArraylike(obj);
                if (args) {
                    if (isArray) {
                        for (; i < length; i++) {
                            value = callback.apply(obj[i], args);
                            if (value === false) {
                                break;
                            }
                        }
                    } else {
                        for (i in obj) {
                            value = callback.apply(obj[i], args);
                            if (value === false) {
                                break;
                            }
                        }
                    }
                } else {
                    if (isArray) {
                        for (; i < length; i++) {
                            value = callback.call(obj[i], i, obj[i]);
                            if (value === false) {
                                break;
                            }
                        }
                    } else {
                        for (i in obj) {
                            value = callback.call(obj[i], i, obj[i]);
                            if (value === false) {
                                break;
                            }
                        }
                    }
                }
                return obj;
            },
            trim: function(text) {
                return text == null ?
                    "" :
                    (text + "").replace(rtrim, "");
            },
            makeArray: function(arr, results) {
                var ret = results || [];
                if (arr != null) {
                    if (isArraylike(Object(arr))) {
                        jQuery.merge(ret,
                            typeof arr === "string" ? [arr] : arr
                        );
                    } else {
                        push.call(ret, arr);
                    }
                }
                return ret;
            },
            inArray: function(elem, arr, i) {
                return arr == null ? -1 : indexOf.call(arr, elem, i);
            },
            merge: function(first, second) {
                var len = +second.length,
                    j = 0,
                    i = first.length;
                for (; j < len; j++) {
                    first[i++] = second[j];
                }
                first.length = i;
                return first;
            },
            grep: function(elems, callback, invert) {
                var callbackInverse,
                    matches = [],
                    i = 0,
                    length = elems.length,
                    callbackExpect = !invert;
                for (; i < length; i++) {
                    callbackInverse = !callback(elems[i], i);
                    if (callbackInverse !== callbackExpect) {
                        matches.push(elems[i]);
                    }
                }
                return matches;
            },
            map: function(elems, callback, arg) {
                var value,
                    i = 0,
                    length = elems.length,
                    isArray = isArraylike(elems),
                    ret = [];
                if (isArray) {
                    for (; i < length; i++) {
                        value = callback(elems[i], i, arg);
                        if (value != null) {
                            ret.push(value);
                        }
                    }
                } else {
                    for (i in elems) {
                        value = callback(elems[i], i, arg);
                        if (value != null) {
                            ret.push(value);
                        }
                    }
                }
                return concat.apply([], ret);
            },
            guid: 1,
            proxy: function(fn, context) {
                var tmp, args, proxy;
                if (typeof context === "string") {
                    tmp = fn[context];
                    context = fn;
                    fn = tmp;
                }
                if (!jQuery.isFunction(fn)) {
                    return undefined;
                }
                args = slice.call(arguments, 2);
                proxy = function() {
                    return fn.apply(context || this, args.concat(slice.call(arguments)));
                };
                proxy.guid = fn.guid = fn.guid || jQuery.guid++;
                return proxy;
            },
            now: Date.now,
            support: support
        });
        jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
            class2type["[object " + name + "]"] = name.toLowerCase();
        });
    
        function isArraylike(obj) {
            var length = "length" in obj && obj.length,
                type = jQuery.type(obj);
            if (type === "function" || jQuery.isWindow(obj)) {
                return false;
            }
            if (obj.nodeType === 1 && length) {
                return true;
            }
            return type === "array" || length === 0 ||
                typeof length === "number" && length > 0 && (length - 1) in obj;
        }
        var Sizzle =
            (function(window) {
                var i,
                    support,
                    Expr,
                    getText,
                    isXML,
                    tokenize,
                    compile,
                    select,
                    outermostContext,
                    sortInput,
                    hasDuplicate,
                    setDocument,
                    document,
                    docElem,
                    documentIsHTML,
                    rbuggyQSA,
                    rbuggyMatches,
                    matches,
                    contains,
                    expando = "sizzle" + 1 * new Date(),
                    preferredDoc = window.document,
                    dirruns = 0,
                    done = 0,
                    classCache = createCache(),
                    tokenCache = createCache(),
                    compilerCache = createCache(),
                    sortOrder = function(a, b) {
                        if (a === b) {
                            hasDuplicate = true;
                        }
                        return 0;
                    },
                    MAX_NEGATIVE = 1 << 31,
                    hasOwn = ({}).hasOwnProperty,
                    arr = [],
                    pop = arr.pop,
                    push_native = arr.push,
                    push = arr.push,
                    slice = arr.slice,
                    indexOf = function(list, elem) {
                        var i = 0,
                            len = list.length;
                        for (; i < len; i++) {
                            if (list[i] === elem) {
                                return i;
                            }
                        }
                        return -1;
                    },
                    booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
                    whitespace = "[\\x20\\t\\r\\n\\f]",
                    characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
                    identifier = characterEncoding.replace("w", "w#"),
                    attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
                    "*([*^$|!~]?=)" + whitespace +
                    "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
                    "*\\]",
                    pseudos = ":(" + characterEncoding + ")(?:\\((" +
                    "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
                    "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
                    ".*" +
                    ")\\)|)",
                    rwhitespace = new RegExp(whitespace + "+", "g"),
                    rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g"),
                    rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"),
                    rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"),
                    rattributeQuotes = new RegExp("=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g"),
                    rpseudo = new RegExp(pseudos),
                    ridentifier = new RegExp("^" + identifier + "$"),
                    matchExpr = {
                        "ID": new RegExp("^#(" + characterEncoding + ")"),
                        "CLASS": new RegExp("^\\.(" + characterEncoding + ")"),
                        "TAG": new RegExp("^(" + characterEncoding.replace("w", "w*") + ")"),
                        "ATTR": new RegExp("^" + attributes),
                        "PSEUDO": new RegExp("^" + pseudos),
                        "CHILD": new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
                            "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
                            "*(\\d+)|))" + whitespace + "*\\)|)", "i"),
                        "bool": new RegExp("^(?:" + booleans + ")$", "i"),
                        "needsContext": new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
                            whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i")
                    },
                    rinputs = /^(?:input|select|textarea|button)$/i,
                    rheader = /^h\d$/i,
                    rnative = /^[^{]+\{\s*\[native \w/,
                    rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
                    rsibling = /[+~]/,
                    rescape = /'|\\/g,
                    runescape = new RegExp("\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig"),
                    funescape = function(_, escaped, escapedWhitespace) {
                        var high = "0x" + escaped - 0x10000;
                        return high !== high || escapedWhitespace ?
                            escaped :
                            high < 0 ?
                            String.fromCharCode(high + 0x10000) :
                            String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00);
                    },
                    unloadHandler = function() {
                        setDocument();
                    };
                try {
                    push.apply(
                        (arr = slice.call(preferredDoc.childNodes)),
                        preferredDoc.childNodes
                    );
                    arr[preferredDoc.childNodes.length].nodeType;
                } catch (e) {
                    push = {
                        apply: arr.length ?
                            function(target, els) {
                                push_native.apply(target, slice.call(els));
                            } : function(target, els) {
                                var j = target.length,
                                    i = 0;
                                while ((target[j++] = els[i++])) {}
                                target.length = j - 1;
                            }
                    };
                }
    
                function Sizzle(selector, context, results, seed) {
                    var match, elem, m, nodeType,
                        i, groups, old, nid, newContext, newSelector;
                    if ((context ? context.ownerDocument || context : preferredDoc) !== document) {
                        setDocument(context);
                    }
                    context = context || document;
                    results = results || [];
                    nodeType = context.nodeType;
                    if (typeof selector !== "string" || !selector ||
                        nodeType !== 1 && nodeType !== 9 && nodeType !== 11) {
                        return results;
                    }
                    if (!seed && documentIsHTML) {
                        if (nodeType !== 11 && (match = rquickExpr.exec(selector))) {
                            if ((m = match[1])) {
                                if (nodeType === 9) {
                                    elem = context.getElementById(m);
                                    if (elem && elem.parentNode) {
                                        if (elem.id === m) {
                                            results.push(elem);
                                            return results;
                                        }
                                    } else {
                                        return results;
                                    }
                                } else {
                                    if (context.ownerDocument && (elem = context.ownerDocument.getElementById(m)) &&
                                        contains(context, elem) && elem.id === m) {
                                        results.push(elem);
                                        return results;
                                    }
                                }
                            } else if (match[2]) {
                                push.apply(results, context.getElementsByTagName(selector));
                                return results;
                            } else if ((m = match[3]) && support.getElementsByClassName) {
                                push.apply(results, context.getElementsByClassName(m));
                                return results;
                            }
                        }
                        if (support.qsa && (!rbuggyQSA || !rbuggyQSA.test(selector))) {
                            nid = old = expando;
                            newContext = context;
                            newSelector = nodeType !== 1 && selector;
                            if (nodeType === 1 && context.nodeName.toLowerCase() !== "object") {
                                groups = tokenize(selector);
                                if ((old = context.getAttribute("id"))) {
                                    nid = old.replace(rescape, "\\$&");
                                } else {
                                    context.setAttribute("id", nid);
                                }
                                nid = "[id='" + nid + "'] ";
                                i = groups.length;
                                while (i--) {
                                    groups[i] = nid + toSelector(groups[i]);
                                }
                                newContext = rsibling.test(selector) && testContext(context.parentNode) || context;
                                newSelector = groups.join(",");
                            }
                            if (newSelector) {
                                try {
                                    push.apply(results,
                                        newContext.querySelectorAll(newSelector)
                                    );
                                    return results;
                                } catch (qsaError) {} finally {
                                    if (!old) {
                                        context.removeAttribute("id");
                                    }
                                }
                            }
                        }
                    }
                    return select(selector.replace(rtrim, "$1"), context, results, seed);
                }
    
                function createCache() {
                    var keys = [];
    
                    function cache(key, value) {
                        if (keys.push(key + " ") > Expr.cacheLength) {
                            delete cache[keys.shift()];
                        }
                        return (cache[key + " "] = value);
                    }
                    return cache;
                }
    
                function markFunction(fn) {
                    fn[expando] = true;
                    return fn;
                }
    
                function assert(fn) {
                    var div = document.createElement("div");
                    try {
                        return !!fn(div);
                    } catch (e) {
                        return false;
                    } finally {
                        if (div.parentNode) {
                            div.parentNode.removeChild(div);
                        }
                        div = null;
                    }
                }
    
                function addHandle(attrs, handler) {
                    var arr = attrs.split("|"),
                        i = attrs.length;
                    while (i--) {
                        Expr.attrHandle[arr[i]] = handler;
                    }
                }
    
                function siblingCheck(a, b) {
                    var cur = b && a,
                        diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
                        (~b.sourceIndex || MAX_NEGATIVE) -
                        (~a.sourceIndex || MAX_NEGATIVE);
                    if (diff) {
                        return diff;
                    }
                    if (cur) {
                        while ((cur = cur.nextSibling)) {
                            if (cur === b) {
                                return -1;
                            }
                        }
                    }
                    return a ? 1 : -1;
                }
    
                function createInputPseudo(type) {
                    return function(elem) {
                        var name = elem.nodeName.toLowerCase();
                        return name === "input" && elem.type === type;
                    };
                }
    
                function createButtonPseudo(type) {
                    return function(elem) {
                        var name = elem.nodeName.toLowerCase();
                        return (name === "input" || name === "button") && elem.type === type;
                    };
                }
    
                function createPositionalPseudo(fn) {
                    return markFunction(function(argument) {
                        argument = +argument;
                        return markFunction(function(seed, matches) {
                            var j,
                                matchIndexes = fn([], seed.length, argument),
                                i = matchIndexes.length;
                            while (i--) {
                                if (seed[(j = matchIndexes[i])]) {
                                    seed[j] = !(matches[j] = seed[j]);
                                }
                            }
                        });
                    });
                }
    
                function testContext(context) {
                    return context && typeof context.getElementsByTagName !== "undefined" && context;
                }
                support = Sizzle.support = {};
                isXML = Sizzle.isXML = function(elem) {
                    var documentElement = elem && (elem.ownerDocument || elem).documentElement;
                    return documentElement ? documentElement.nodeName !== "HTML" : false;
                };
                setDocument = Sizzle.setDocument = function(node) {
                    var hasCompare, parent,
                        doc = node ? node.ownerDocument || node : preferredDoc;
                    if (doc === document || doc.nodeType !== 9 || !doc.documentElement) {
                        return document;
                    }
                    document = doc;
                    docElem = doc.documentElement;
                    parent = doc.defaultView;
                    if (parent && parent !== parent.top) {
                        if (parent.addEventListener) {
                            parent.addEventListener("unload", unloadHandler, false);
                        } else if (parent.attachEvent) {
                            parent.attachEvent("onunload", unloadHandler);
                        }
                    }
                    documentIsHTML = !isXML(doc);
                    support.attributes = assert(function(div) {
                        div.className = "i";
                        return !div.getAttribute("className");
                    });
                    support.getElementsByTagName = assert(function(div) {
                        div.appendChild(doc.createComment(""));
                        return !div.getElementsByTagName("*").length;
                    });
                    support.getElementsByClassName = rnative.test(doc.getElementsByClassName);
                    support.getById = assert(function(div) {
                        docElem.appendChild(div).id = expando;
                        return !doc.getElementsByName || !doc.getElementsByName(expando).length;
                    });
                    if (support.getById) {
                        Expr.find["ID"] = function(id, context) {
                            if (typeof context.getElementById !== "undefined" && documentIsHTML) {
                                var m = context.getElementById(id);
                                return m && m.parentNode ? [m] : [];
                            }
                        };
                        Expr.filter["ID"] = function(id) {
                            var attrId = id.replace(runescape, funescape);
                            return function(elem) {
                                return elem.getAttribute("id") === attrId;
                            };
                        };
                    } else {
                        delete Expr.find["ID"];
                        Expr.filter["ID"] = function(id) {
                            var attrId = id.replace(runescape, funescape);
                            return function(elem) {
                                var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
                                return node && node.value === attrId;
                            };
                        };
                    }
                    Expr.find["TAG"] = support.getElementsByTagName ?
                        function(tag, context) {
                            if (typeof context.getElementsByTagName !== "undefined") {
                                return context.getElementsByTagName(tag);
                            } else if (support.qsa) {
                                return context.querySelectorAll(tag);
                            }
                        } :
                        function(tag, context) {
                            var elem,
                                tmp = [],
                                i = 0,
                                results = context.getElementsByTagName(tag);
                            if (tag === "*") {
                                while ((elem = results[i++])) {
                                    if (elem.nodeType === 1) {
                                        tmp.push(elem);
                                    }
                                }
                                return tmp;
                            }
                            return results;
                        };
                    Expr.find["CLASS"] = support.getElementsByClassName && function(className, context) {
                        if (documentIsHTML) {
                            return context.getElementsByClassName(className);
                        }
                    };
                    rbuggyMatches = [];
                    rbuggyQSA = [];
                    if ((support.qsa = rnative.test(doc.querySelectorAll))) {
                        assert(function(div) {
                            docElem.appendChild(div).innerHTML = "<a id='" + expando + "'></a>" +
                                "<select id='" + expando + "-\f]' msallowcapture=''>" +
                                "<option selected=''></option></select>";
                            if (div.querySelectorAll("[msallowcapture^='']").length) {
                                rbuggyQSA.push("[*^$]=" + whitespace + "*(?:''|\"\")");
                            }
                            if (!div.querySelectorAll("[selected]").length) {
                                rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")");
                            }
                            if (!div.querySelectorAll("[id~=" + expando + "-]").length) {
                                rbuggyQSA.push("~=");
                            }
                            if (!div.querySelectorAll(":checked").length) {
                                rbuggyQSA.push(":checked");
                            }
                            if (!div.querySelectorAll("a#" + expando + "+*").length) {
                                rbuggyQSA.push(".#.+[+~]");
                            }
                        });
                        assert(function(div) {
                            var input = doc.createElement("input");
                            input.setAttribute("type", "hidden");
                            div.appendChild(input).setAttribute("name", "D");
                            if (div.querySelectorAll("[name=d]").length) {
                                rbuggyQSA.push("name" + whitespace + "*[*^$|!~]?=");
                            }
                            if (!div.querySelectorAll(":enabled").length) {
                                rbuggyQSA.push(":enabled", ":disabled");
                            }
                            div.querySelectorAll("*,:x");
                            rbuggyQSA.push(",.*:");
                        });
                    }
                    if ((support.matchesSelector = rnative.test((matches = docElem.matches ||
                            docElem.webkitMatchesSelector ||
                            docElem.mozMatchesSelector ||
                            docElem.oMatchesSelector ||
                            docElem.msMatchesSelector)))) {
                        assert(function(div) {
                            support.disconnectedMatch = matches.call(div, "div");
                            matches.call(div, "[s!='']:x");
                            rbuggyMatches.push("!=", pseudos);
                        });
                    }
                    rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|"));
                    rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|"));
                    hasCompare = rnative.test(docElem.compareDocumentPosition);
                    contains = hasCompare || rnative.test(docElem.contains) ?
                        function(a, b) {
                            var adown = a.nodeType === 9 ? a.documentElement : a,
                                bup = b && b.parentNode;
                            return a === bup || !!(bup && bup.nodeType === 1 && (
                                adown.contains ?
                                adown.contains(bup) :
                                a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16
                            ));
                        } :
                        function(a, b) {
                            if (b) {
                                while ((b = b.parentNode)) {
                                    if (b === a) {
                                        return true;
                                    }
                                }
                            }
                            return false;
                        };
                    sortOrder = hasCompare ?
                        function(a, b) {
                            if (a === b) {
                                hasDuplicate = true;
                                return 0;
                            }
                            var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
                            if (compare) {
                                return compare;
                            }
                            compare = (a.ownerDocument || a) === (b.ownerDocument || b) ?
                                a.compareDocumentPosition(b) :
                                1;
                            if (compare & 1 ||
                                (!support.sortDetached && b.compareDocumentPosition(a) === compare)) {
                                if (a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) {
                                    return -1;
                                }
                                if (b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) {
                                    return 1;
                                }
                                return sortInput ?
                                    (indexOf(sortInput, a) - indexOf(sortInput, b)) :
                                    0;
                            }
                            return compare & 4 ? -1 : 1;
                        } :
                        function(a, b) {
                            if (a === b) {
                                hasDuplicate = true;
                                return 0;
                            }
                            var cur,
                                i = 0,
                                aup = a.parentNode,
                                bup = b.parentNode,
                                ap = [a],
                                bp = [b];
                            if (!aup || !bup) {
                                return a === doc ? -1 :
                                    b === doc ? 1 :
                                    aup ? -1 :
                                    bup ? 1 :
                                    sortInput ?
                                    (indexOf(sortInput, a) - indexOf(sortInput, b)) :
                                    0;
                            } else if (aup === bup) {
                                return siblingCheck(a, b);
                            }
                            cur = a;
                            while ((cur = cur.parentNode)) {
                                ap.unshift(cur);
                            }
                            cur = b;
                            while ((cur = cur.parentNode)) {
                                bp.unshift(cur);
                            }
                            while (ap[i] === bp[i]) {
                                i++;
                            }
                            return i ?
                                siblingCheck(ap[i], bp[i]) :
                                ap[i] === preferredDoc ? -1 :
                                bp[i] === preferredDoc ? 1 :
                                0;
                        };
                    return doc;
                };
                Sizzle.matches = function(expr, elements) {
                    return Sizzle(expr, null, null, elements);
                };
                Sizzle.matchesSelector = function(elem, expr) {
                    if ((elem.ownerDocument || elem) !== document) {
                        setDocument(elem);
                    }
                    expr = expr.replace(rattributeQuotes, "='$1']");
                    if (support.matchesSelector && documentIsHTML &&
                        (!rbuggyMatches || !rbuggyMatches.test(expr)) &&
                        (!rbuggyQSA || !rbuggyQSA.test(expr))) {
                        try {
                            var ret = matches.call(elem, expr);
                            if (ret || support.disconnectedMatch ||
                                elem.document && elem.document.nodeType !== 11) {
                                return ret;
                            }
                        } catch (e) {}
                    }
                    return Sizzle(expr, document, null, [elem]).length > 0;
                };
                Sizzle.contains = function(context, elem) {
                    if ((context.ownerDocument || context) !== document) {
                        setDocument(context);
                    }
                    return contains(context, elem);
                };
                Sizzle.attr = function(elem, name) {
                    if ((elem.ownerDocument || elem) !== document) {
                        setDocument(elem);
                    }
                    var fn = Expr.attrHandle[name.toLowerCase()],
                        val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ?
                        fn(elem, name, !documentIsHTML) :
                        undefined;
                    return val !== undefined ?
                        val :
                        support.attributes || !documentIsHTML ?
                        elem.getAttribute(name) :
                        (val = elem.getAttributeNode(name)) && val.specified ?
                        val.value :
                        null;
                };
                Sizzle.error = function(msg) {
                    throw new Error("Syntax error, unrecognized expression: " + msg);
                };
                Sizzle.uniqueSort = function(results) {
                    var elem,
                        duplicates = [],
                        j = 0,
                        i = 0;
                    hasDuplicate = !support.detectDuplicates;
                    sortInput = !support.sortStable && results.slice(0);
                    results.sort(sortOrder);
                    if (hasDuplicate) {
                        while ((elem = results[i++])) {
                            if (elem === results[i]) {
                                j = duplicates.push(i);
                            }
                        }
                        while (j--) {
                            results.splice(duplicates[j], 1);
                        }
                    }
                    sortInput = null;
                    return results;
                };
                getText = Sizzle.getText = function(elem) {
                    var node,
                        ret = "",
                        i = 0,
                        nodeType = elem.nodeType;
                    if (!nodeType) {
                        while ((node = elem[i++])) {
                            ret += getText(node);
                        }
                    } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {
                        if (typeof elem.textContent === "string") {
                            return elem.textContent;
                        } else {
                            for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
                                ret += getText(elem);
                            }
                        }
                    } else if (nodeType === 3 || nodeType === 4) {
                        return elem.nodeValue;
                    }
                    return ret;
                };
                Expr = Sizzle.selectors = {
                    cacheLength: 50,
                    createPseudo: markFunction,
                    match: matchExpr,
                    attrHandle: {},
                    find: {},
                    relative: {
                        ">": {
                            dir: "parentNode",
                            first: true
                        },
                        " ": {
                            dir: "parentNode"
                        },
                        "+": {
                            dir: "previousSibling",
                            first: true
                        },
                        "~": {
                            dir: "previousSibling"
                        }
                    },
                    preFilter: {
                        "ATTR": function(match) {
                            match[1] = match[1].replace(runescape, funescape);
                            match[3] = (match[3] || match[4] || match[5] || "").replace(runescape, funescape);
                            if (match[2] === "~=") {
                                match[3] = " " + match[3] + " ";
                            }
                            return match.slice(0, 4);
                        },
                        "CHILD": function(match) {
                            match[1] = match[1].toLowerCase();
                            if (match[1].slice(0, 3) === "nth") {
                                if (!match[3]) {
                                    Sizzle.error(match[0]);
                                }
                                match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd"));
                                match[5] = +((match[7] + match[8]) || match[3] === "odd");
                            } else if (match[3]) {
                                Sizzle.error(match[0]);
                            }
                            return match;
                        },
                        "PSEUDO": function(match) {
                            var excess,
                                unquoted = !match[6] && match[2];
                            if (matchExpr["CHILD"].test(match[0])) {
                                return null;
                            }
                            if (match[3]) {
                                match[2] = match[4] || match[5] || "";
                            } else if (unquoted && rpseudo.test(unquoted) &&
                                (excess = tokenize(unquoted, true)) &&
                                (excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) {
                                match[0] = match[0].slice(0, excess);
                                match[2] = unquoted.slice(0, excess);
                            }
                            return match.slice(0, 3);
                        }
                    },
                    filter: {
                        "TAG": function(nodeNameSelector) {
                            var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();
                            return nodeNameSelector === "*" ?
                                function() {
                                    return true;
                                } :
                                function(elem) {
                                    return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
                                };
                        },
                        "CLASS": function(className) {
                            var pattern = classCache[className + " "];
                            return pattern ||
                                (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) &&
                                classCache(className, function(elem) {
                                    return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "");
                                });
                        },
                        "ATTR": function(name, operator, check) {
                            return function(elem) {
                                var result = Sizzle.attr(elem, name);
                                if (result == null) {
                                    return operator === "!=";
                                }
                                if (!operator) {
                                    return true;
                                }
                                result += "";
                                return operator === "=" ? result === check :
                                    operator === "!=" ? result !== check :
                                    operator === "^=" ? check && result.indexOf(check) === 0 :
                                    operator === "*=" ? check && result.indexOf(check) > -1 :
                                    operator === "$=" ? check && result.slice(-check.length) === check :
                                    operator === "~=" ? (" " + result.replace(rwhitespace, " ") + " ").indexOf(check) > -1 :
                                    operator === "|=" ? result === check || result.slice(0, check.length + 1) === check + "-" :
                                    false;
                            };
                        },
                        "CHILD": function(type, what, argument, first, last) {
                            var simple = type.slice(0, 3) !== "nth",
                                forward = type.slice(-4) !== "last",
                                ofType = what === "of-type";
                            return first === 1 && last === 0 ?
                                function(elem) {
                                    return !!elem.parentNode;
                                } :
                                function(elem, context, xml) {
                                    var cache, outerCache, node, diff, nodeIndex, start,
                                        dir = simple !== forward ? "nextSibling" : "previousSibling",
                                        parent = elem.parentNode,
                                        name = ofType && elem.nodeName.toLowerCase(),
                                        useCache = !xml && !ofType;
                                    if (parent) {
                                        if (simple) {
                                            while (dir) {
                                                node = elem;
                                                while ((node = node[dir])) {
                                                    if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) {
                                                        return false;
                                                    }
                                                }
                                                start = dir = type === "only" && !start && "nextSibling";
                                            }
                                            return true;
                                        }
                                        start = [forward ? parent.firstChild : parent.lastChild];
                                        if (forward && useCache) {
                                            outerCache = parent[expando] || (parent[expando] = {});
                                            cache = outerCache[type] || [];
                                            nodeIndex = cache[0] === dirruns && cache[1];
                                            diff = cache[0] === dirruns && cache[2];
                                            node = nodeIndex && parent.childNodes[nodeIndex];
                                            while ((node = ++nodeIndex && node && node[dir] ||
                                                    (diff = nodeIndex = 0) || start.pop())) {
                                                if (node.nodeType === 1 && ++diff && node === elem) {
                                                    outerCache[type] = [dirruns, nodeIndex, diff];
                                                    break;
                                                }
                                            }
                                        } else if (useCache && (cache = (elem[expando] || (elem[expando] = {}))[type]) && cache[0] === dirruns) {
                                            diff = cache[1];
                                        } else {
                                            while ((node = ++nodeIndex && node && node[dir] ||
                                                    (diff = nodeIndex = 0) || start.pop())) {
                                                if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) {
                                                    if (useCache) {
                                                        (node[expando] || (node[expando] = {}))[type] = [dirruns, diff];
                                                    }
                                                    if (node === elem) {
                                                        break;
                                                    }
                                                }
                                            }
                                        }
                                        diff -= last;
                                        return diff === first || (diff % first === 0 && diff / first >= 0);
                                    }
                                };
                        },
                        "PSEUDO": function(pseudo, argument) {
                            var args,
                                fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] ||
                                Sizzle.error("unsupported pseudo: " + pseudo);
                            if (fn[expando]) {
                                return fn(argument);
                            }
                            if (fn.length > 1) {
                                args = [pseudo, pseudo, "", argument];
                                return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ?
                                    markFunction(function(seed, matches) {
                                        var idx,
                                            matched = fn(seed, argument),
                                            i = matched.length;
                                        while (i--) {
                                            idx = indexOf(seed, matched[i]);
                                            seed[idx] = !(matches[idx] = matched[i]);
                                        }
                                    }) :
                                    function(elem) {
                                        return fn(elem, 0, args);
                                    };
                            }
                            return fn;
                        }
                    },
                    pseudos: {
                        "not": markFunction(function(selector) {
                            var input = [],
                                results = [],
                                matcher = compile(selector.replace(rtrim, "$1"));
                            return matcher[expando] ?
                                markFunction(function(seed, matches, context, xml) {
                                    var elem,
                                        unmatched = matcher(seed, null, xml, []),
                                        i = seed.length;
                                    while (i--) {
                                        if ((elem = unmatched[i])) {
                                            seed[i] = !(matches[i] = elem);
                                        }
                                    }
                                }) :
                                function(elem, context, xml) {
                                    input[0] = elem;
                                    matcher(input, null, xml, results);
                                    input[0] = null;
                                    return !results.pop();
                                };
                        }),
                        "has": markFunction(function(selector) {
                            return function(elem) {
                                return Sizzle(selector, elem).length > 0;
                            };
                        }),
                        "contains": markFunction(function(text) {
                            text = text.replace(runescape, funescape);
                            return function(elem) {
                                return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1;
                            };
                        }),
                        "lang": markFunction(function(lang) {
                            if (!ridentifier.test(lang || "")) {
                                Sizzle.error("unsupported lang: " + lang);
                            }
                            lang = lang.replace(runescape, funescape).toLowerCase();
                            return function(elem) {
                                var elemLang;
                                do {
                                    if ((elemLang = documentIsHTML ?
                                            elem.lang :
                                            elem.getAttribute("xml:lang") || elem.getAttribute("lang"))) {
                                        elemLang = elemLang.toLowerCase();
                                        return elemLang === lang || elemLang.indexOf(lang + "-") === 0;
                                    }
                                } while ((elem = elem.parentNode) && elem.nodeType === 1);
                                return false;
                            };
                        }),
                        "target": function(elem) {
                            var hash = window.location && window.location.hash;
                            return hash && hash.slice(1) === elem.id;
                        },
                        "root": function(elem) {
                            return elem === docElem;
                        },
                        "focus": function(elem) {
                            return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
                        },
                        "enabled": function(elem) {
                            return elem.disabled === false;
                        },
                        "disabled": function(elem) {
                            return elem.disabled === true;
                        },
                        "checked": function(elem) {
                            var nodeName = elem.nodeName.toLowerCase();
                            return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
                        },
                        "selected": function(elem) {
                            if (elem.parentNode) {
                                elem.parentNode.selectedIndex;
                            }
                            return elem.selected === true;
                        },
                        "empty": function(elem) {
                            for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
                                if (elem.nodeType < 6) {
                                    return false;
                                }
                            }
                            return true;
                        },
                        "parent": function(elem) {
                            return !Expr.pseudos["empty"](elem);
                        },
                        "header": function(elem) {
                            return rheader.test(elem.nodeName);
                        },
                        "input": function(elem) {
                            return rinputs.test(elem.nodeName);
                        },
                        "button": function(elem) {
                            var name = elem.nodeName.toLowerCase();
                            return name === "input" && elem.type === "button" || name === "button";
                        },
                        "text": function(elem) {
                            var attr;
                            return elem.nodeName.toLowerCase() === "input" &&
                                elem.type === "text" &&
                                ((attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text");
                        },
                        "first": createPositionalPseudo(function() {
                            return [0];
                        }),
                        "last": createPositionalPseudo(function(matchIndexes, length) {
                            return [length - 1];
                        }),
                        "eq": createPositionalPseudo(function(matchIndexes, length, argument) {
                            return [argument < 0 ? argument + length : argument];
                        }),
                        "even": createPositionalPseudo(function(matchIndexes, length) {
                            var i = 0;
                            for (; i < length; i += 2) {
                                matchIndexes.push(i);
                            }
                            return matchIndexes;
                        }),
                        "odd": createPositionalPseudo(function(matchIndexes, length) {
                            var i = 1;
                            for (; i < length; i += 2) {
                                matchIndexes.push(i);
                            }
                            return matchIndexes;
                        }),
                        "lt": createPositionalPseudo(function(matchIndexes, length, argument) {
                            var i = argument < 0 ? argument + length : argument;
                            for (; --i >= 0;) {
                                matchIndexes.push(i);
                            }
                            return matchIndexes;
                        }),
                        "gt": createPositionalPseudo(function(matchIndexes, length, argument) {
                            var i = argument < 0 ? argument + length : argument;
                            for (; ++i < length;) {
                                matchIndexes.push(i);
                            }
                            return matchIndexes;
                        })
                    }
                };
                Expr.pseudos["nth"] = Expr.pseudos["eq"];
                for (i in {
                        radio: true,
                        checkbox: true,
                        file: true,
                        password: true,
                        image: true
                    }) {
                    Expr.pseudos[i] = createInputPseudo(i);
                }
                for (i in {
                        submit: true,
                        reset: true
                    }) {
                    Expr.pseudos[i] = createButtonPseudo(i);
                }
    
                function setFilters() {}
                setFilters.prototype = Expr.filters = Expr.pseudos;
                Expr.setFilters = new setFilters();
                tokenize = Sizzle.tokenize = function(selector, parseOnly) {
                    var matched, match, tokens, type,
                        soFar, groups, preFilters,
                        cached = tokenCache[selector + " "];
                    if (cached) {
                        return parseOnly ? 0 : cached.slice(0);
                    }
                    soFar = selector;
                    groups = [];
                    preFilters = Expr.preFilter;
                    while (soFar) {
                        if (!matched || (match = rcomma.exec(soFar))) {
                            if (match) {
                                soFar = soFar.slice(match[0].length) || soFar;
                            }
                            groups.push((tokens = []));
                        }
                        matched = false;
                        if ((match = rcombinators.exec(soFar))) {
                            matched = match.shift();
                            tokens.push({
                                value: matched,
                                type: match[0].replace(rtrim, " ")
                            });
                            soFar = soFar.slice(matched.length);
                        }
                        for (type in Expr.filter) {
                            if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] ||
                                    (match = preFilters[type](match)))) {
                                matched = match.shift();
                                tokens.push({
                                    value: matched,
                                    type: type,
                                    matches: match
                                });
                                soFar = soFar.slice(matched.length);
                            }
                        }
                        if (!matched) {
                            break;
                        }
                    }
                    return parseOnly ?
                        soFar.length :
                        soFar ?
                        Sizzle.error(selector) :
                        tokenCache(selector, groups).slice(0);
                };
    
                function toSelector(tokens) {
                    var i = 0,
                        len = tokens.length,
                        selector = "";
                    for (; i < len; i++) {
                        selector += tokens[i].value;
                    }
                    return selector;
                }
    
                function addCombinator(matcher, combinator, base) {
                    var dir = combinator.dir,
                        checkNonElements = base && dir === "parentNode",
                        doneName = done++;
                    return combinator.first ?
                        function(elem, context, xml) {
                            while ((elem = elem[dir])) {
                                if (elem.nodeType === 1 || checkNonElements) {
                                    return matcher(elem, context, xml);
                                }
                            }
                        } :
                        function(elem, context, xml) {
                            var oldCache, outerCache,
                                newCache = [dirruns, doneName];
                            if (xml) {
                                while ((elem = elem[dir])) {
                                    if (elem.nodeType === 1 || checkNonElements) {
                                        if (matcher(elem, context, xml)) {
                                            return true;
                                        }
                                    }
                                }
                            } else {
                                while ((elem = elem[dir])) {
                                    if (elem.nodeType === 1 || checkNonElements) {
                                        outerCache = elem[expando] || (elem[expando] = {});
                                        if ((oldCache = outerCache[dir]) &&
                                            oldCache[0] === dirruns && oldCache[1] === doneName) {
                                            return (newCache[2] = oldCache[2]);
                                        } else {
                                            outerCache[dir] = newCache;
                                            if ((newCache[2] = matcher(elem, context, xml))) {
                                                return true;
                                            }
                                        }
                                    }
                                }
                            }
                        };
                }
    
                function elementMatcher(matchers) {
                    return matchers.length > 1 ?
                        function(elem, context, xml) {
                            var i = matchers.length;
                            while (i--) {
                                if (!matchers[i](elem, context, xml)) {
                                    return false;
                                }
                            }
                            return true;
                        } :
                        matchers[0];
                }
    
                function multipleContexts(selector, contexts, results) {
                    var i = 0,
                        len = contexts.length;
                    for (; i < len; i++) {
                        Sizzle(selector, contexts[i], results);
                    }
                    return results;
                }
    
                function condense(unmatched, map, filter, context, xml) {
                    var elem,
                        newUnmatched = [],
                        i = 0,
                        len = unmatched.length,
                        mapped = map != null;
                    for (; i < len; i++) {
                        if ((elem = unmatched[i])) {
                            if (!filter || filter(elem, context, xml)) {
                                newUnmatched.push(elem);
                                if (mapped) {
                                    map.push(i);
                                }
                            }
                        }
                    }
                    return newUnmatched;
                }
    
                function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
                    if (postFilter && !postFilter[expando]) {
                        postFilter = setMatcher(postFilter);
                    }
                    if (postFinder && !postFinder[expando]) {
                        postFinder = setMatcher(postFinder, postSelector);
                    }
                    return markFunction(function(seed, results, context, xml) {
                        var temp, i, elem,
                            preMap = [],
                            postMap = [],
                            preexisting = results.length,
                            elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []),
                            matcherIn = preFilter && (seed || !selector) ?
                            condense(elems, preMap, preFilter, context, xml) :
                            elems,
                            matcherOut = matcher ?
                            postFinder || (seed ? preFilter : preexisting || postFilter) ? [] :
                            results :
                            matcherIn;
                        if (matcher) {
                            matcher(matcherIn, matcherOut, context, xml);
                        }
                        if (postFilter) {
                            temp = condense(matcherOut, postMap);
                            postFilter(temp, [], context, xml);
                            i = temp.length;
                            while (i--) {
                                if ((elem = temp[i])) {
                                    matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
                                }
                            }
                        }
                        if (seed) {
                            if (postFinder || preFilter) {
                                if (postFinder) {
                                    temp = [];
                                    i = matcherOut.length;
                                    while (i--) {
                                        if ((elem = matcherOut[i])) {
                                            temp.push((matcherIn[i] = elem));
                                        }
                                    }
                                    postFinder(null, (matcherOut = []), temp, xml);
                                }
                                i = matcherOut.length;
                                while (i--) {
                                    if ((elem = matcherOut[i]) &&
                                        (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) {
                                        seed[temp] = !(results[temp] = elem);
                                    }
                                }
                            }
                        } else {
                            matcherOut = condense(
                                matcherOut === results ?
                                matcherOut.splice(preexisting, matcherOut.length) :
                                matcherOut
                            );
                            if (postFinder) {
                                postFinder(null, results, matcherOut, xml);
                            } else {
                                push.apply(results, matcherOut);
                            }
                        }
                    });
                }
    
                function matcherFromTokens(tokens) {
                    var checkContext, matcher, j,
                        len = tokens.length,
                        leadingRelative = Expr.relative[tokens[0].type],
                        implicitRelative = leadingRelative || Expr.relative[" "],
                        i = leadingRelative ? 1 : 0,
                        matchContext = addCombinator(function(elem) {
                            return elem === checkContext;
                        }, implicitRelative, true),
                        matchAnyContext = addCombinator(function(elem) {
                            return indexOf(checkContext, elem) > -1;
                        }, implicitRelative, true),
                        matchers = [function(elem, context, xml) {
                            var ret = (!leadingRelative && (xml || context !== outermostContext)) || (
                                (checkContext = context).nodeType ?
                                matchContext(elem, context, xml) :
                                matchAnyContext(elem, context, xml));
                            checkContext = null;
                            return ret;
                        }];
                    for (; i < len; i++) {
                        if ((matcher = Expr.relative[tokens[i].type])) {
                            matchers = [addCombinator(elementMatcher(matchers), matcher)];
                        } else {
                            matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);
                            if (matcher[expando]) {
                                j = ++i;
                                for (; j < len; j++) {
                                    if (Expr.relative[tokens[j].type]) {
                                        break;
                                    }
                                }
                                return setMatcher(
                                    i > 1 && elementMatcher(matchers),
                                    i > 1 && toSelector(
                                        tokens.slice(0, i - 1).concat({
                                            value: tokens[i - 2].type === " " ? "*" : ""
                                        })
                                    ).replace(rtrim, "$1"),
                                    matcher,
                                    i < j && matcherFromTokens(tokens.slice(i, j)),
                                    j < len && matcherFromTokens((tokens = tokens.slice(j))),
                                    j < len && toSelector(tokens)
                                );
                            }
                            matchers.push(matcher);
                        }
                    }
                    return elementMatcher(matchers);
                }
    
                function matcherFromGroupMatchers(elementMatchers, setMatchers) {
                    var bySet = setMatchers.length > 0,
                        byElement = elementMatchers.length > 0,
                        superMatcher = function(seed, context, xml, results, outermost) {
                            var elem, j, matcher,
                                matchedCount = 0,
                                i = "0",
                                unmatched = seed && [],
                                setMatched = [],
                                contextBackup = outermostContext,
                                elems = seed || byElement && Expr.find["TAG"]("*", outermost),
                                dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
                                len = elems.length;
                            if (outermost) {
                                outermostContext = context !== document && context;
                            }
                            for (; i !== len && (elem = elems[i]) != null; i++) {
                                if (byElement && elem) {
                                    j = 0;
                                    while ((matcher = elementMatchers[j++])) {
                                        if (matcher(elem, context, xml)) {
                                            results.push(elem);
                                            break;
                                        }
                                    }
                                    if (outermost) {
                                        dirruns = dirrunsUnique;
                                    }
                                }
                                if (bySet) {
                                    if ((elem = !matcher && elem)) {
                                        matchedCount--;
                                    }
                                    if (seed) {
                                        unmatched.push(elem);
                                    }
                                }
                            }
                            matchedCount += i;
                            if (bySet && i !== matchedCount) {
                                j = 0;
                                while ((matcher = setMatchers[j++])) {
                                    matcher(unmatched, setMatched, context, xml);
                                }
                                if (seed) {
                                    if (matchedCount > 0) {
                                        while (i--) {
                                            if (!(unmatched[i] || setMatched[i])) {
                                                setMatched[i] = pop.call(results);
                                            }
                                        }
                                    }
                                    setMatched = condense(setMatched);
                                }
                                push.apply(results, setMatched);
                                if (outermost && !seed && setMatched.length > 0 &&
                                    (matchedCount + setMatchers.length) > 1) {
                                    Sizzle.uniqueSort(results);
                                }
                            }
                            if (outermost) {
                                dirruns = dirrunsUnique;
                                outermostContext = contextBackup;
                            }
                            return unmatched;
                        };
                    return bySet ?
                        markFunction(superMatcher) :
                        superMatcher;
                }
                compile = Sizzle.compile = function(selector, match) {
                    var i,
                        setMatchers = [],
                        elementMatchers = [],
                        cached = compilerCache[selector + " "];
                    if (!cached) {
                        if (!match) {
                            match = tokenize(selector);
                        }
                        i = match.length;
                        while (i--) {
                            cached = matcherFromTokens(match[i]);
                            if (cached[expando]) {
                                setMatchers.push(cached);
                            } else {
                                elementMatchers.push(cached);
                            }
                        }
                        cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers));
                        cached.selector = selector;
                    }
                    return cached;
                };
                select = Sizzle.select = function(selector, context, results, seed) {
                    var i, tokens, token, type, find,
                        compiled = typeof selector === "function" && selector,
                        match = !seed && tokenize((selector = compiled.selector || selector));
                    results = results || [];
                    if (match.length === 1) {
                        tokens = match[0] = match[0].slice(0);
                        if (tokens.length > 2 && (token = tokens[0]).type === "ID" &&
                            support.getById && context.nodeType === 9 && documentIsHTML &&
                            Expr.relative[tokens[1].type]) {
                            context = (Expr.find["ID"](token.matches[0].replace(runescape, funescape), context) || [])[0];
                            if (!context) {
                                return results;
                            } else if (compiled) {
                                context = context.parentNode;
                            }
                            selector = selector.slice(tokens.shift().value.length);
                        }
                        i = matchExpr["needsContext"].test(selector) ? 0 : tokens.length;
                        while (i--) {
                            token = tokens[i];
                            if (Expr.relative[(type = token.type)]) {
                                break;
                            }
                            if ((find = Expr.find[type])) {
                                if ((seed = find(
                                        token.matches[0].replace(runescape, funescape),
                                        rsibling.test(tokens[0].type) && testContext(context.parentNode) || context
                                    ))) {
                                    tokens.splice(i, 1);
                                    selector = seed.length && toSelector(tokens);
                                    if (!selector) {
                                        push.apply(results, seed);
                                        return results;
                                    }
                                    break;
                                }
                            }
                        }
                    }
                    (compiled || compile(selector, match))(
                        seed,
                        context, !documentIsHTML,
                        results,
                        rsibling.test(selector) && testContext(context.parentNode) || context
                    );
                    return results;
                };
                support.sortStable = expando.split("").sort(sortOrder).join("") === expando;
                support.detectDuplicates = !!hasDuplicate;
                setDocument();
                support.sortDetached = assert(function(div1) {
                    return div1.compareDocumentPosition(document.createElement("div")) & 1;
                });
                if (!assert(function(div) {
                        div.innerHTML = "<a href='#'></a>";
                        return div.firstChild.getAttribute("href") === "#";
                    })) {
                    addHandle("type|href|height|width", function(elem, name, isXML) {
                        if (!isXML) {
                            return elem.getAttribute(name, name.toLowerCase() === "type" ? 1 : 2);
                        }
                    });
                }
                if (!support.attributes || !assert(function(div) {
                        div.innerHTML = "<input/>";
                        div.firstChild.setAttribute("value", "");
                        return div.firstChild.getAttribute("value") === "";
                    })) {
                    addHandle("value", function(elem, name, isXML) {
                        if (!isXML && elem.nodeName.toLowerCase() === "input") {
                            return elem.defaultValue;
                        }
                    });
                }
                if (!assert(function(div) {
                        return div.getAttribute("disabled") == null;
                    })) {
                    addHandle(booleans, function(elem, name, isXML) {
                        var val;
                        if (!isXML) {
                            return elem[name] === true ? name.toLowerCase() :
                                (val = elem.getAttributeNode(name)) && val.specified ?
                                val.value :
                                null;
                        }
                    });
                }
                return Sizzle;
            })(window);
        jQuery.find = Sizzle;
        jQuery.expr = Sizzle.selectors;
        jQuery.expr[":"] = jQuery.expr.pseudos;
        jQuery.unique = Sizzle.uniqueSort;
        jQuery.text = Sizzle.getText;
        jQuery.isXMLDoc = Sizzle.isXML;
        jQuery.contains = Sizzle.contains;
        var rneedsContext = jQuery.expr.match.needsContext;
        var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
        var risSimple = /^.[^:#\[\.,]*$/;
    
        function winnow(elements, qualifier, not) {
            if (jQuery.isFunction(qualifier)) {
                return jQuery.grep(elements, function(elem, i) {
                    return !!qualifier.call(elem, i, elem) !== not;
                });
            }
            if (qualifier.nodeType) {
                return jQuery.grep(elements, function(elem) {
                    return (elem === qualifier) !== not;
                });
            }
            if (typeof qualifier === "string") {
                if (risSimple.test(qualifier)) {
                    return jQuery.filter(qualifier, elements, not);
                }
                qualifier = jQuery.filter(qualifier, elements);
            }
            return jQuery.grep(elements, function(elem) {
                return (indexOf.call(qualifier, elem) >= 0) !== not;
            });
        }
        jQuery.filter = function(expr, elems, not) {
            var elem = elems[0];
            if (not) {
                expr = ":not(" + expr + ")";
            }
            return elems.length === 1 && elem.nodeType === 1 ?
                jQuery.find.matchesSelector(elem, expr) ? [elem] : [] :
                jQuery.find.matches(expr, jQuery.grep(elems, function(elem) {
                    return elem.nodeType === 1;
                }));
        };
        jQuery.fn.extend({
            find: function(selector) {
                var i,
                    len = this.length,
                    ret = [],
                    self = this;
                if (typeof selector !== "string") {
                    return this.pushStack(jQuery(selector).filter(function() {
                        for (i = 0; i < len; i++) {
                            if (jQuery.contains(self[i], this)) {
                                return true;
                            }
                        }
                    }));
                }
                for (i = 0; i < len; i++) {
                    jQuery.find(selector, self[i], ret);
                }
                ret = this.pushStack(len > 1 ? jQuery.unique(ret) : ret);
                ret.selector = this.selector ? this.selector + " " + selector : selector;
                return ret;
            },
            filter: function(selector) {
                return this.pushStack(winnow(this, selector || [], false));
            },
            not: function(selector) {
                return this.pushStack(winnow(this, selector || [], true));
            },
            is: function(selector) {
                return !!winnow(
                    this,
                    typeof selector === "string" && rneedsContext.test(selector) ?
                    jQuery(selector) :
                    selector || [],
                    false
                ).length;
            }
        });
        var rootjQuery,
            rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
            init = jQuery.fn.init = function(selector, context) {
                var match, elem;
                if (!selector) {
                    return this;
                }
                if (typeof selector === "string") {
                    if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) {
                        match = [null, selector, null];
                    } else {
                        match = rquickExpr.exec(selector);
                    }
                    if (match && (match[1] || !context)) {
                        if (match[1]) {
                            context = context instanceof jQuery ? context[0] : context;
                            jQuery.merge(this, jQuery.parseHTML(
                                match[1],
                                context && context.nodeType ? context.ownerDocument || context : document,
                                true
                            ));
                            if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
                                for (match in context) {
                                    if (jQuery.isFunction(this[match])) {
                                        this[match](context[match]);
                                    } else {
                                        this.attr(match, context[match]);
                                    }
                                }
                            }
                            return this;
                        } else {
                            elem = document.getElementById(match[2]);
                            if (elem && elem.parentNode) {
                                this.length = 1;
                                this[0] = elem;
                            }
                            this.context = document;
                            this.selector = selector;
                            return this;
                        }
                    } else if (!context || context.jquery) {
                        return (context || rootjQuery).find(selector);
                    } else {
                        return this.constructor(context).find(selector);
                    }
                } else if (selector.nodeType) {
                    this.context = this[0] = selector;
                    this.length = 1;
                    return this;
                } else if (jQuery.isFunction(selector)) {
                    return typeof rootjQuery.ready !== "undefined" ?
                        rootjQuery.ready(selector) :
                        selector(jQuery);
                }
                if (selector.selector !== undefined) {
                    this.selector = selector.selector;
                    this.context = selector.context;
                }
                return jQuery.makeArray(selector, this);
            };
        init.prototype = jQuery.fn;
        rootjQuery = jQuery(document);
        var rparentsprev = /^(?:parents|prev(?:Until|All))/,
            guaranteedUnique = {
                children: true,
                contents: true,
                next: true,
                prev: true
            };
        jQuery.extend({
            dir: function(elem, dir, until) {
                var matched = [],
                    truncate = until !== undefined;
                while ((elem = elem[dir]) && elem.nodeType !== 9) {
                    if (elem.nodeType === 1) {
                        if (truncate && jQuery(elem).is(until)) {
                            break;
                        }
                        matched.push(elem);
                    }
                }
                return matched;
            },
            sibling: function(n, elem) {
                var matched = [];
                for (; n; n = n.nextSibling) {
                    if (n.nodeType === 1 && n !== elem) {
                        matched.push(n);
                    }
                }
                return matched;
            }
        });
        jQuery.fn.extend({
            has: function(target) {
                var targets = jQuery(target, this),
                    l = targets.length;
                return this.filter(function() {
                    var i = 0;
                    for (; i < l; i++) {
                        if (jQuery.contains(this, targets[i])) {
                            return true;
                        }
                    }
                });
            },
            closest: function(selectors, context) {
                var cur,
                    i = 0,
                    l = this.length,
                    matched = [],
                    pos = rneedsContext.test(selectors) || typeof selectors !== "string" ?
                    jQuery(selectors, context || this.context) :
                    0;
                for (; i < l; i++) {
                    for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) {
                        if (cur.nodeType < 11 && (pos ?
                                pos.index(cur) > -1 :
                                cur.nodeType === 1 &&
                                jQuery.find.matchesSelector(cur, selectors))) {
                            matched.push(cur);
                            break;
                        }
                    }
                }
                return this.pushStack(matched.length > 1 ? jQuery.unique(matched) : matched);
            },
            index: function(elem) {
                if (!elem) {
                    return (this[0] && this[0].parentNode) ? this.first().prevAll().length : -1;
                }
                if (typeof elem === "string") {
                    return indexOf.call(jQuery(elem), this[0]);
                }
                return indexOf.call(this,
                    elem.jquery ? elem[0] : elem
                );
            },
            add: function(selector, context) {
                return this.pushStack(
                    jQuery.unique(
                        jQuery.merge(this.get(), jQuery(selector, context))
                    )
                );
            },
            addBack: function(selector) {
                return this.add(selector == null ?
                    this.prevObject : this.prevObject.filter(selector)
                );
            }
        });
    
        function sibling(cur, dir) {
            while ((cur = cur[dir]) && cur.nodeType !== 1) {}
            return cur;
        }
        jQuery.each({
            parent: function(elem) {
                var parent = elem.parentNode;
                return parent && parent.nodeType !== 11 ? parent : null;
            },
            parents: function(elem) {
                return jQuery.dir(elem, "parentNode");
            },
            parentsUntil: function(elem, i, until) {
                return jQuery.dir(elem, "parentNode", until);
            },
            next: function(elem) {
                return sibling(elem, "nextSibling");
            },
            prev: function(elem) {
                return sibling(elem, "previousSibling");
            },
            nextAll: function(elem) {
                return jQuery.dir(elem, "nextSibling");
            },
            prevAll: function(elem) {
                return jQuery.dir(elem, "previousSibling");
            },
            nextUntil: function(elem, i, until) {
                return jQuery.dir(elem, "nextSibling", until);
            },
            prevUntil: function(elem, i, until) {
                return jQuery.dir(elem, "previousSibling", until);
            },
            siblings: function(elem) {
                return jQuery.sibling((elem.parentNode || {}).firstChild, elem);
            },
            children: function(elem) {
                return jQuery.sibling(elem.firstChild);
            },
            contents: function(elem) {
                return elem.contentDocument || jQuery.merge([], elem.childNodes);
            }
        }, function(name, fn) {
            jQuery.fn[name] = function(until, selector) {
                var matched = jQuery.map(this, fn, until);
                if (name.slice(-5) !== "Until") {
                    selector = until;
                }
                if (selector && typeof selector === "string") {
                    matched = jQuery.filter(selector, matched);
                }
                if (this.length > 1) {
                    if (!guaranteedUnique[name]) {
                        jQuery.unique(matched);
                    }
                    if (rparentsprev.test(name)) {
                        matched.reverse();
                    }
                }
                return this.pushStack(matched);
            };
        });
        var rnotwhite = (/\S+/g);
        var optionsCache = {};
    
        function createOptions(options) {
            var object = optionsCache[options] = {};
            jQuery.each(options.match(rnotwhite) || [], function(_, flag) {
                object[flag] = true;
            });
            return object;
        }
        jQuery.Callbacks = function(options) {
            options = typeof options === "string" ?
                (optionsCache[options] || createOptions(options)) :
                jQuery.extend({}, options);
            var
                memory,
                fired,
                firing,
                firingStart,
                firingLength,
                firingIndex,
                list = [],
                stack = !options.once && [],
                fire = function(data) {
                    memory = options.memory && data;
                    fired = true;
                    firingIndex = firingStart || 0;
                    firingStart = 0;
                    firingLength = list.length;
                    firing = true;
                    for (; list && firingIndex < firingLength; firingIndex++) {
                        if (list[firingIndex].apply(data[0], data[1]) === false && options.stopOnFalse) {
                            memory = false;
                            break;
                        }
                    }
                    firing = false;
                    if (list) {
                        if (stack) {
                            if (stack.length) {
                                fire(stack.shift());
                            }
                        } else if (memory) {
                            list = [];
                        } else {
                            self.disable();
                        }
                    }
                },
                self = {
                    add: function() {
                        if (list) {
                            var start = list.length;
                            (function add(args) {
                                jQuery.each(args, function(_, arg) {
                                    var type = jQuery.type(arg);
                                    if (type === "function") {
                                        if (!options.unique || !self.has(arg)) {
                                            list.push(arg);
                                        }
                                    } else if (arg && arg.length && type !== "string") {
                                        add(arg);
                                    }
                                });
                            })(arguments);
                            if (firing) {
                                firingLength = list.length;
                            } else if (memory) {
                                firingStart = start;
                                fire(memory);
                            }
                        }
                        return this;
                    },
                    remove: function() {
                        if (list) {
                            jQuery.each(arguments, function(_, arg) {
                                var index;
                                while ((index = jQuery.inArray(arg, list, index)) > -1) {
                                    list.splice(index, 1);
                                    if (firing) {
                                        if (index <= firingLength) {
                                            firingLength--;
                                        }
                                        if (index <= firingIndex) {
                                            firingIndex--;
                                        }
                                    }
                                }
                            });
                        }
                        return this;
                    },
                    has: function(fn) {
                        return fn ? jQuery.inArray(fn, list) > -1 : !!(list && list.length);
                    },
                    empty: function() {
                        list = [];
                        firingLength = 0;
                        return this;
                    },
                    disable: function() {
                        list = stack = memory = undefined;
                        return this;
                    },
                    disabled: function() {
                        return !list;
                    },
                    lock: function() {
                        stack = undefined;
                        if (!memory) {
                            self.disable();
                        }
                        return this;
                    },
                    locked: function() {
                        return !stack;
                    },
                    fireWith: function(context, args) {
                        if (list && (!fired || stack)) {
                            args = args || [];
                            args = [context, args.slice ? args.slice() : args];
                            if (firing) {
                                stack.push(args);
                            } else {
                                fire(args);
                            }
                        }
                        return this;
                    },
                    fire: function() {
                        self.fireWith(this, arguments);
                        return this;
                    },
                    fired: function() {
                        return !!fired;
                    }
                };
            return self;
        };
        jQuery.extend({
            Deferred: function(func) {
                var tuples = [
                        ["resolve", "done", jQuery.Callbacks("once memory"), "resolved"],
                        ["reject", "fail", jQuery.Callbacks("once memory"), "rejected"],
                        ["notify", "progress", jQuery.Callbacks("memory")]
                    ],
                    state = "pending",
                    promise = {
                        state: function() {
                            return state;
                        },
                        always: function() {
                            deferred.done(arguments).fail(arguments);
                            return this;
                        },
                        then: function() {
                            var fns = arguments;
                            return jQuery.Deferred(function(newDefer) {
                                jQuery.each(tuples, function(i, tuple) {
                                    var fn = jQuery.isFunction(fns[i]) && fns[i];
                                    deferred[tuple[1]](function() {
                                        var returned = fn && fn.apply(this, arguments);
                                        if (returned && jQuery.isFunction(returned.promise)) {
                                            returned.promise()
                                                .done(newDefer.resolve)
                                                .fail(newDefer.reject)
                                                .progress(newDefer.notify);
                                        } else {
                                            newDefer[tuple[0] + "With"](this === promise ? newDefer.promise() : this, fn ? [returned] : arguments);
                                        }
                                    });
                                });
                                fns = null;
                            }).promise();
                        },
                        promise: function(obj) {
                            return obj != null ? jQuery.extend(obj, promise) : promise;
                        }
                    },
                    deferred = {};
                promise.pipe = promise.then;
                jQuery.each(tuples, function(i, tuple) {
                    var list = tuple[2],
                        stateString = tuple[3];
                    promise[tuple[1]] = list.add;
                    if (stateString) {
                        list.add(function() {
                            state = stateString;
                        }, tuples[i ^ 1][2].disable, tuples[2][2].lock);
                    }
                    deferred[tuple[0]] = function() {
                        deferred[tuple[0] + "With"](this === deferred ? promise : this, arguments);
                        return this;
                    };
                    deferred[tuple[0] + "With"] = list.fireWith;
                });
                promise.promise(deferred);
                if (func) {
                    func.call(deferred, deferred);
                }
                return deferred;
            },
            when: function(subordinate) {
                var i = 0,
                    resolveValues = slice.call(arguments),
                    length = resolveValues.length,
                    remaining = length !== 1 || (subordinate && jQuery.isFunction(subordinate.promise)) ? length : 0,
                    deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
                    updateFunc = function(i, contexts, values) {
                        return function(value) {
                            contexts[i] = this;
                            values[i] = arguments.length > 1 ? slice.call(arguments) : value;
                            if (values === progressValues) {
                                deferred.notifyWith(contexts, values);
                            } else if (!(--remaining)) {
                                deferred.resolveWith(contexts, values);
                            }
                        };
                    },
                    progressValues, progressContexts, resolveContexts;
                if (length > 1) {
                    progressValues = new Array(length);
                    progressContexts = new Array(length);
                    resolveContexts = new Array(length);
                    for (; i < length; i++) {
                        if (resolveValues[i] && jQuery.isFunction(resolveValues[i].promise)) {
                            resolveValues[i].promise()
                                .done(updateFunc(i, resolveContexts, resolveValues))
                                .fail(deferred.reject)
                                .progress(updateFunc(i, progressContexts, progressValues));
                        } else {
                            --remaining;
                        }
                    }
                }
                if (!remaining) {
                    deferred.resolveWith(resolveContexts, resolveValues);
                }
                return deferred.promise();
            }
        });
        var readyList;
        jQuery.fn.ready = function(fn) {
            jQuery.ready.promise().done(fn);
            return this;
        };
        jQuery.extend({
            isReady: false,
            readyWait: 1,
            holdReady: function(hold) {
                if (hold) {
                    jQuery.readyWait++;
                } else {
                    jQuery.ready(true);
                }
            },
            ready: function(wait) {
                if (wait === true ? --jQuery.readyWait : jQuery.isReady) {
                    return;
                }
                jQuery.isReady = true;
                if (wait !== true && --jQuery.readyWait > 0) {
                    return;
                }
                readyList.resolveWith(document, [jQuery]);
                if (jQuery.fn.triggerHandler) {
                    jQuery(document).triggerHandler("ready");
                    jQuery(document).off("ready");
                }
            }
        });
    
        function completed() {
            document.removeEventListener("DOMContentLoaded", completed, false);
            window.removeEventListener("load", completed, false);
            jQuery.ready();
        }
        jQuery.ready.promise = function(obj) {
            if (!readyList) {
                readyList = jQuery.Deferred();
                if (document.readyState === "complete") {
                    setTimeout(jQuery.ready);
                } else {
                    document.addEventListener("DOMContentLoaded", completed, false);
                    window.addEventListener("load", completed, false);
                }
            }
            return readyList.promise(obj);
        };
        jQuery.ready.promise();
        var access = jQuery.access = function(elems, fn, key, value, chainable, emptyGet, raw) {
            var i = 0,
                len = elems.length,
                bulk = key == null;
            if (jQuery.type(key) === "object") {
                chainable = true;
                for (i in key) {
                    jQuery.access(elems, fn, i, key[i], true, emptyGet, raw);
                }
            } else if (value !== undefined) {
                chainable = true;
                if (!jQuery.isFunction(value)) {
                    raw = true;
                }
                if (bulk) {
                    if (raw) {
                        fn.call(elems, value);
                        fn = null;
                    } else {
                        bulk = fn;
                        fn = function(elem, key, value) {
                            return bulk.call(jQuery(elem), value);
                        };
                    }
                }
                if (fn) {
                    for (; i < len; i++) {
                        fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key)));
                    }
                }
            }
            return chainable ?
                elems :
                bulk ?
                fn.call(elems) :
                len ? fn(elems[0], key) : emptyGet;
        };
        jQuery.acceptData = function(owner) {
            return owner.nodeType === 1 || owner.nodeType === 9 || !(+owner.nodeType);
        };
    
        function Data() {
            Object.defineProperty(this.cache = {}, 0, {
                get: function() {
                    return {};
                }
            });
            this.expando = jQuery.expando + Data.uid++;
        }
        Data.uid = 1;
        Data.accepts = jQuery.acceptData;
        Data.prototype = {
            key: function(owner) {
                if (!Data.accepts(owner)) {
                    return 0;
                }
                var descriptor = {},
                    unlock = owner[this.expando];
                if (!unlock) {
                    unlock = Data.uid++;
                    try {
                        descriptor[this.expando] = {
                            value: unlock
                        };
                        Object.defineProperties(owner, descriptor);
                    } catch (e) {
                        descriptor[this.expando] = unlock;
                        jQuery.extend(owner, descriptor);
                    }
                }
                if (!this.cache[unlock]) {
                    this.cache[unlock] = {};
                }
                return unlock;
            },
            set: function(owner, data, value) {
                var prop,
                    unlock = this.key(owner),
                    cache = this.cache[unlock];
                if (typeof data === "string") {
                    cache[data] = value;
                } else {
                    if (jQuery.isEmptyObject(cache)) {
                        jQuery.extend(this.cache[unlock], data);
                    } else {
                        for (prop in data) {
                            cache[prop] = data[prop];
                        }
                    }
                }
                return cache;
            },
            get: function(owner, key) {
                var cache = this.cache[this.key(owner)];
                return key === undefined ?
                    cache : cache[key];
            },
            access: function(owner, key, value) {
                var stored;
                if (key === undefined ||
                    ((key && typeof key === "string") && value === undefined)) {
                    stored = this.get(owner, key);
                    return stored !== undefined ?
                        stored : this.get(owner, jQuery.camelCase(key));
                }
                this.set(owner, key, value);
                return value !== undefined ? value : key;
            },
            remove: function(owner, key) {
                var i, name, camel,
                    unlock = this.key(owner),
                    cache = this.cache[unlock];
                if (key === undefined) {
                    this.cache[unlock] = {};
                } else {
                    if (jQuery.isArray(key)) {
                        name = key.concat(key.map(jQuery.camelCase));
                    } else {
                        camel = jQuery.camelCase(key);
                        if (key in cache) {
                            name = [key, camel];
                        } else {
                            name = camel;
                            name = name in cache ? [name] : (name.match(rnotwhite) || []);
                        }
                    }
                    i = name.length;
                    while (i--) {
                        delete cache[name[i]];
                    }
                }
            },
            hasData: function(owner) {
                return !jQuery.isEmptyObject(
                    this.cache[owner[this.expando]] || {}
                );
            },
            discard: function(owner) {
                if (owner[this.expando]) {
                    delete this.cache[owner[this.expando]];
                }
            }
        };
        var data_priv = new Data();
        var data_user = new Data();
        var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
            rmultiDash = /([A-Z])/g;
    
        function dataAttr(elem, key, data) {
            var name;
            if (data === undefined && elem.nodeType === 1) {
                name = "data-" + key.replace(rmultiDash, "-$1").toLowerCase();
                data = elem.getAttribute(name);
                if (typeof data === "string") {
                    try {
                        data = data === "true" ? true :
                            data === "false" ? false :
                            data === "null" ? null :
                            +data + "" === data ? +data :
                            rbrace.test(data) ? jQuery.parseJSON(data) :
                            data;
                    } catch (e) {}
                    data_user.set(elem, key, data);
                } else {
                    data = undefined;
                }
            }
            return data;
        }
        jQuery.extend({
            hasData: function(elem) {
                return data_user.hasData(elem) || data_priv.hasData(elem);
            },
            data: function(elem, name, data) {
                return data_user.access(elem, name, data);
            },
            removeData: function(elem, name) {
                data_user.remove(elem, name);
            },
            _data: function(elem, name, data) {
                return data_priv.access(elem, name, data);
            },
            _removeData: function(elem, name) {
                data_priv.remove(elem, name);
            }
        });
        jQuery.fn.extend({
            data: function(key, value) {
                var i, name, data,
                    elem = this[0],
                    attrs = elem && elem.attributes;
                if (key === undefined) {
                    if (this.length) {
                        data = data_user.get(elem);
                        if (elem.nodeType === 1 && !data_priv.get(elem, "hasDataAttrs")) {
                            i = attrs.length;
                            while (i--) {
                                if (attrs[i]) {
                                    name = attrs[i].name;
                                    if (name.indexOf("data-") === 0) {
                                        name = jQuery.camelCase(name.slice(5));
                                        dataAttr(elem, name, data[name]);
                                    }
                                }
                            }
                            data_priv.set(elem, "hasDataAttrs", true);
                        }
                    }
                    return data;
                }
                if (typeof key === "object") {
                    return this.each(function() {
                        data_user.set(this, key);
                    });
                }
                return access(this, function(value) {
                    var data,
                        camelKey = jQuery.camelCase(key);
                    if (elem && value === undefined) {
                        data = data_user.get(elem, key);
                        if (data !== undefined) {
                            return data;
                        }
                        data = data_user.get(elem, camelKey);
                        if (data !== undefined) {
                            return data;
                        }
                        data = dataAttr(elem, camelKey, undefined);
                        if (data !== undefined) {
                            return data;
                        }
                        return;
                    }
                    this.each(function() {
                        var data = data_user.get(this, camelKey);
                        data_user.set(this, camelKey, value);
                        if (key.indexOf("-") !== -1 && data !== undefined) {
                            data_user.set(this, key, value);
                        }
                    });
                }, null, value, arguments.length > 1, null, true);
            },
            removeData: function(key) {
                return this.each(function() {
                    data_user.remove(this, key);
                });
            }
        });
        jQuery.extend({
            queue: function(elem, type, data) {
                var queue;
                if (elem) {
                    type = (type || "fx") + "queue";
                    queue = data_priv.get(elem, type);
                    if (data) {
                        if (!queue || jQuery.isArray(data)) {
                            queue = data_priv.access(elem, type, jQuery.makeArray(data));
                        } else {
                            queue.push(data);
                        }
                    }
                    return queue || [];
                }
            },
            dequeue: function(elem, type) {
                type = type || "fx";
                var queue = jQuery.queue(elem, type),
                    startLength = queue.length,
                    fn = queue.shift(),
                    hooks = jQuery._queueHooks(elem, type),
                    next = function() {
                        jQuery.dequeue(elem, type);
                    };
                if (fn === "inprogress") {
                    fn = queue.shift();
                    startLength--;
                }
                if (fn) {
                    if (type === "fx") {
                        queue.unshift("inprogress");
                    }
                    delete hooks.stop;
                    fn.call(elem, next, hooks);
                }
                if (!startLength && hooks) {
                    hooks.empty.fire();
                }
            },
            _queueHooks: function(elem, type) {
                var key = type + "queueHooks";
                return data_priv.get(elem, key) || data_priv.access(elem, key, {
                    empty: jQuery.Callbacks("once memory").add(function() {
                        data_priv.remove(elem, [type + "queue", key]);
                    })
                });
            }
        });
        jQuery.fn.extend({
            queue: function(type, data) {
                var setter = 2;
                if (typeof type !== "string") {
                    data = type;
                    type = "fx";
                    setter--;
                }
                if (arguments.length < setter) {
                    return jQuery.queue(this[0], type);
                }
                return data === undefined ?
                    this :
                    this.each(function() {
                        var queue = jQuery.queue(this, type, data);
                        jQuery._queueHooks(this, type);
                        if (type === "fx" && queue[0] !== "inprogress") {
                            jQuery.dequeue(this, type);
                        }
                    });
            },
            dequeue: function(type) {
                return this.each(function() {
                    jQuery.dequeue(this, type);
                });
            },
            clearQueue: function(type) {
                return this.queue(type || "fx", []);
            },
            promise: function(type, obj) {
                var tmp,
                    count = 1,
                    defer = jQuery.Deferred(),
                    elements = this,
                    i = this.length,
                    resolve = function() {
                        if (!(--count)) {
                            defer.resolveWith(elements, [elements]);
                        }
                    };
                if (typeof type !== "string") {
                    obj = type;
                    type = undefined;
                }
                type = type || "fx";
                while (i--) {
                    tmp = data_priv.get(elements[i], type + "queueHooks");
                    if (tmp && tmp.empty) {
                        count++;
                        tmp.empty.add(resolve);
                    }
                }
                resolve();
                return defer.promise(obj);
            }
        });
        var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
        var cssExpand = ["Top", "Right", "Bottom", "Left"];
        var isHidden = function(elem, el) {
            elem = el || elem;
            return jQuery.css(elem, "display") === "none" || !jQuery.contains(elem.ownerDocument, elem);
        };
        var rcheckableType = (/^(?:checkbox|radio)$/i);
        (function() {
            var fragment = document.createDocumentFragment(),
                div = fragment.appendChild(document.createElement("div")),
                input = document.createElement("input");
            input.setAttribute("type", "radio");
            input.setAttribute("checked", "checked");
            input.setAttribute("name", "t");
            div.appendChild(input);
            support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked;
            div.innerHTML = "<textarea>x</textarea>";
            support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue;
        })();
        var strundefined = typeof undefined;
        support.focusinBubbles = "onfocusin" in window;
        var
            rkeyEvent = /^key/,
            rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
            rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
            rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
    
        function returnTrue() {
            return true;
        }
    
        function returnFalse() {
            return false;
        }
    
        function safeActiveElement() {
            try {
                return document.activeElement;
            } catch (err) {}
        }
        jQuery.event = {
            global: {},
            add: function(elem, types, handler, data, selector) {
                var handleObjIn, eventHandle, tmp,
                    events, t, handleObj,
                    special, handlers, type, namespaces, origType,
                    elemData = data_priv.get(elem);
                if (!elemData) {
                    return;
                }
                if (handler.handler) {
                    handleObjIn = handler;
                    handler = handleObjIn.handler;
                    selector = handleObjIn.selector;
                }
                if (!handler.guid) {
                    handler.guid = jQuery.guid++;
                }
                if (!(events = elemData.events)) {
                    events = elemData.events = {};
                }
                if (!(eventHandle = elemData.handle)) {
                    eventHandle = elemData.handle = function(e) {
                        return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?
                            jQuery.event.dispatch.apply(elem, arguments) : undefined;
                    };
                }
                types = (types || "").match(rnotwhite) || [""];
                t = types.length;
                while (t--) {
                    tmp = rtypenamespace.exec(types[t]) || [];
                    type = origType = tmp[1];
                    namespaces = (tmp[2] || "").split(".").sort();
                    if (!type) {
                        continue;
                    }
                    special = jQuery.event.special[type] || {};
                    type = (selector ? special.delegateType : special.bindType) || type;
                    special = jQuery.event.special[type] || {};
                    handleObj = jQuery.extend({
                        type: type,
                        origType: origType,
                        data: data,
                        handler: handler,
                        guid: handler.guid,
                        selector: selector,
                        needsContext: selector && jQuery.expr.match.needsContext.test(selector),
                        namespace: namespaces.join(".")
                    }, handleObjIn);
                    if (!(handlers = events[type])) {
                        handlers = events[type] = [];
                        handlers.delegateCount = 0;
                        if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {
                            if (elem.addEventListener) {
                                elem.addEventListener(type, eventHandle, false);
                            }
                        }
                    }
                    if (special.add) {
                        special.add.call(elem, handleObj);
                        if (!handleObj.handler.guid) {
                            handleObj.handler.guid = handler.guid;
                        }
                    }
                    if (selector) {
                        handlers.splice(handlers.delegateCount++, 0, handleObj);
                    } else {
                        handlers.push(handleObj);
                    }
                    jQuery.event.global[type] = true;
                }
            },
            remove: function(elem, types, handler, selector, mappedTypes) {
                var j, origCount, tmp,
                    events, t, handleObj,
                    special, handlers, type, namespaces, origType,
                    elemData = data_priv.hasData(elem) && data_priv.get(elem);
                if (!elemData || !(events = elemData.events)) {
                    return;
                }
                types = (types || "").match(rnotwhite) || [""];
                t = types.length;
                while (t--) {
                    tmp = rtypenamespace.exec(types[t]) || [];
                    type = origType = tmp[1];
                    namespaces = (tmp[2] || "").split(".").sort();
                    if (!type) {
                        for (type in events) {
                            jQuery.event.remove(elem, type + types[t], handler, selector, true);
                        }
                        continue;
                    }
                    special = jQuery.event.special[type] || {};
                    type = (selector ? special.delegateType : special.bindType) || type;
                    handlers = events[type] || [];
                    tmp = tmp[2] && new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)");
                    origCount = j = handlers.length;
                    while (j--) {
                        handleObj = handlers[j];
                        if ((mappedTypes || origType === handleObj.origType) &&
                            (!handler || handler.guid === handleObj.guid) &&
                            (!tmp || tmp.test(handleObj.namespace)) &&
                            (!selector || selector === handleObj.selector || selector === "**" && handleObj.selector)) {
                            handlers.splice(j, 1);
                            if (handleObj.selector) {
                                handlers.delegateCount--;
                            }
                            if (special.remove) {
                                special.remove.call(elem, handleObj);
                            }
                        }
                    }
                    if (origCount && !handlers.length) {
                        if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) {
                            jQuery.removeEvent(elem, type, elemData.handle);
                        }
                        delete events[type];
                    }
                }
                if (jQuery.isEmptyObject(events)) {
                    delete elemData.handle;
                    data_priv.remove(elem, "events");
                }
            },
            trigger: function(event, data, elem, onlyHandlers) {
                var i, cur, tmp, bubbleType, ontype, handle, special,
                    eventPath = [elem || document],
                    type = hasOwn.call(event, "type") ? event.type : event,
                    namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : [];
                cur = tmp = elem = elem || document;
                if (elem.nodeType === 3 || elem.nodeType === 8) {
                    return;
                }
                if (rfocusMorph.test(type + jQuery.event.triggered)) {
                    return;
                }
                if (type.indexOf(".") >= 0) {
                    namespaces = type.split(".");
                    type = namespaces.shift();
                    namespaces.sort();
                }
                ontype = type.indexOf(":") < 0 && "on" + type;
                event = event[jQuery.expando] ?
                    event :
                    new jQuery.Event(type, typeof event === "object" && event);
                event.isTrigger = onlyHandlers ? 2 : 3;
                event.namespace = namespaces.join(".");
                event.namespace_re = event.namespace ?
                    new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") :
                    null;
                event.result = undefined;
                if (!event.target) {
                    event.target = elem;
                }
                data = data == null ? [event] :
                    jQuery.makeArray(data, [event]);
                special = jQuery.event.special[type] || {};
                if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {
                    return;
                }
                if (!onlyHandlers && !special.noBubble && !jQuery.isWindow(elem)) {
                    bubbleType = special.delegateType || type;
                    if (!rfocusMorph.test(bubbleType + type)) {
                        cur = cur.parentNode;
                    }
                    for (; cur; cur = cur.parentNode) {
                        eventPath.push(cur);
                        tmp = cur;
                    }
                    if (tmp === (elem.ownerDocument || document)) {
                        eventPath.push(tmp.defaultView || tmp.parentWindow || window);
                    }
                }
                i = 0;
                while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {
                    event.type = i > 1 ?
                        bubbleType :
                        special.bindType || type;
                    handle = (data_priv.get(cur, "events") || {})[event.type] && data_priv.get(cur, "handle");
                    if (handle) {
                        handle.apply(cur, data);
                    }
                    handle = ontype && cur[ontype];
                    if (handle && handle.apply && jQuery.acceptData(cur)) {
                        event.result = handle.apply(cur, data);
                        if (event.result === false) {
                            event.preventDefault();
                        }
                    }
                }
                event.type = type;
                if (!onlyHandlers && !event.isDefaultPrevented()) {
                    if ((!special._default || special._default.apply(eventPath.pop(), data) === false) &&
                        jQuery.acceptData(elem)) {
                        if (ontype && jQuery.isFunction(elem[type]) && !jQuery.isWindow(elem)) {
                            tmp = elem[ontype];
                            if (tmp) {
                                elem[ontype] = null;
                            }
                            jQuery.event.triggered = type;
                            elem[type]();
                            jQuery.event.triggered = undefined;
                            if (tmp) {
                                elem[ontype] = tmp;
                            }
                        }
                    }
                }
                return event.result;
            },
            dispatch: function(event) {
                event = jQuery.event.fix(event);
                var i, j, ret, matched, handleObj,
                    handlerQueue = [],
                    args = slice.call(arguments),
                    handlers = (data_priv.get(this, "events") || {})[event.type] || [],
                    special = jQuery.event.special[event.type] || {};
                args[0] = event;
                event.delegateTarget = this;
                if (special.preDispatch && special.preDispatch.call(this, event) === false) {
                    return;
                }
                handlerQueue = jQuery.event.handlers.call(this, event, handlers);
                i = 0;
                while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {
                    event.currentTarget = matched.elem;
                    j = 0;
                    while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) {
                        if (!event.namespace_re || event.namespace_re.test(handleObj.namespace)) {
                            event.handleObj = handleObj;
                            event.data = handleObj.data;
                            ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler)
                                .apply(matched.elem, args);
                            if (ret !== undefined) {
                                if ((event.result = ret) === false) {
                                    event.preventDefault();
                                    event.stopPropagation();
                                }
                            }
                        }
                    }
                }
                if (special.postDispatch) {
                    special.postDispatch.call(this, event);
                }
                return event.result;
            },
            handlers: function(event, handlers) {
                var i, matches, sel, handleObj,
                    handlerQueue = [],
                    delegateCount = handlers.delegateCount,
                    cur = event.target;
                if (delegateCount && cur.nodeType && (!event.button || event.type !== "click")) {
                    for (; cur !== this; cur = cur.parentNode || this) {
                        if (cur.disabled !== true || event.type !== "click") {
                            matches = [];
                            for (i = 0; i < delegateCount; i++) {
                                handleObj = handlers[i];
                                sel = handleObj.selector + " ";
                                if (matches[sel] === undefined) {
                                    matches[sel] = handleObj.needsContext ?
                                        jQuery(sel, this).index(cur) >= 0 :
                                        jQuery.find(sel, this, null, [cur]).length;
                                }
                                if (matches[sel]) {
                                    matches.push(handleObj);
                                }
                            }
                            if (matches.length) {
                                handlerQueue.push({
                                    elem: cur,
                                    handlers: matches
                                });
                            }
                        }
                    }
                }
                if (delegateCount < handlers.length) {
                    handlerQueue.push({
                        elem: this,
                        handlers: handlers.slice(delegateCount)
                    });
                }
                return handlerQueue;
            },
            props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
            fixHooks: {},
            keyHooks: {
                props: "char charCode key keyCode".split(" "),
                filter: function(event, original) {
                    if (event.which == null) {
                        event.which = original.charCode != null ? original.charCode : original.keyCode;
                    }
                    return event;
                }
            },
            mouseHooks: {
                props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
                filter: function(event, original) {
                    var eventDoc, doc, body,
                        button = original.button;
                    if (event.pageX == null && original.clientX != null) {
                        eventDoc = event.target.ownerDocument || document;
                        doc = eventDoc.documentElement;
                        body = eventDoc.body;
                        event.pageX = original.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
                        event.pageY = original.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
                    }
                    if (!event.which && button !== undefined) {
                        event.which = (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0)));
                    }
                    return event;
                }
            },
            fix: function(event) {
                if (event[jQuery.expando]) {
                    return event;
                }
                var i, prop, copy,
                    type = event.type,
                    originalEvent = event,
                    fixHook = this.fixHooks[type];
                if (!fixHook) {
                    this.fixHooks[type] = fixHook =
                        rmouseEvent.test(type) ? this.mouseHooks :
                        rkeyEvent.test(type) ? this.keyHooks : {};
                }
                copy = fixHook.props ? this.props.concat(fixHook.props) : this.props;
                event = new jQuery.Event(originalEvent);
                i = copy.length;
                while (i--) {
                    prop = copy[i];
                    event[prop] = originalEvent[prop];
                }
                if (!event.target) {
                    event.target = document;
                }
                if (event.target.nodeType === 3) {
                    event.target = event.target.parentNode;
                }
                return fixHook.filter ? fixHook.filter(event, originalEvent) : event;
            },
            special: {
                load: {
                    noBubble: true
                },
                focus: {
                    trigger: function() {
                        if (this !== safeActiveElement() && this.focus) {
                            this.focus();
                            return false;
                        }
                    },
                    delegateType: "focusin"
                },
                blur: {
                    trigger: function() {
                        if (this === safeActiveElement() && this.blur) {
                            this.blur();
                            return false;
                        }
                    },
                    delegateType: "focusout"
                },
                click: {
                    trigger: function() {
                        if (this.type === "checkbox" && this.click && jQuery.nodeName(this, "input")) {
                            this.click();
                            return false;
                        }
                    },
                    _default: function(event) {
                        return jQuery.nodeName(event.target, "a");
                    }
                },
                beforeunload: {
                    postDispatch: function(event) {
                        if (event.result !== undefined && event.originalEvent) {
                            event.originalEvent.returnValue = event.result;
                        }
                    }
                }
            },
            simulate: function(type, elem, event, bubble) {
                var e = jQuery.extend(
                    new jQuery.Event(),
                    event, {
                        type: type,
                        isSimulated: true,
                        originalEvent: {}
                    }
                );
                if (bubble) {
                    jQuery.event.trigger(e, null, elem);
                } else {
                    jQuery.event.dispatch.call(elem, e);
                }
                if (e.isDefaultPrevented()) {
                    event.preventDefault();
                }
            }
        };
        jQuery.removeEvent = function(elem, type, handle) {
            if (elem.removeEventListener) {
                elem.removeEventListener(type, handle, false);
            }
        };
        jQuery.Event = function(src, props) {
            if (!(this instanceof jQuery.Event)) {
                return new jQuery.Event(src, props);
            }
            if (src && src.type) {
                this.originalEvent = src;
                this.type = src.type;
                this.isDefaultPrevented = src.defaultPrevented ||
                    src.defaultPrevented === undefined &&
                    src.returnValue === false ?
                    returnTrue :
                    returnFalse;
            } else {
                this.type = src;
            }
            if (props) {
                jQuery.extend(this, props);
            }
            this.timeStamp = src && src.timeStamp || jQuery.now();
            this[jQuery.expando] = true;
        };
        jQuery.Event.prototype = {
            isDefaultPrevented: returnFalse,
            isPropagationStopped: returnFalse,
            isImmediatePropagationStopped: returnFalse,
            preventDefault: function() {
                var e = this.originalEvent;
                this.isDefaultPrevented = returnTrue;
                if (e && e.preventDefault) {
                    e.preventDefault();
                }
            },
            stopPropagation: function() {
                var e = this.originalEvent;
                this.isPropagationStopped = returnTrue;
                if (e && e.stopPropagation) {
                    e.stopPropagation();
                }
            },
            stopImmediatePropagation: function() {
                var e = this.originalEvent;
                this.isImmediatePropagationStopped = returnTrue;
                if (e && e.stopImmediatePropagation) {
                    e.stopImmediatePropagation();
                }
                this.stopPropagation();
            }
        };
        jQuery.each({
            mouseenter: "mouseover",
            mouseleave: "mouseout",
            pointerenter: "pointerover",
            pointerleave: "pointerout"
        }, function(orig, fix) {
            jQuery.event.special[orig] = {
                delegateType: fix,
                bindType: fix,
                handle: function(event) {
                    var ret,
                        target = this,
                        related = event.relatedTarget,
                        handleObj = event.handleObj;
                    if (!related || (related !== target && !jQuery.contains(target, related))) {
                        event.type = handleObj.origType;
                        ret = handleObj.handler.apply(this, arguments);
                        event.type = fix;
                    }
                    return ret;
                }
            };
        });
        if (!support.focusinBubbles) {
            jQuery.each({
                focus: "focusin",
                blur: "focusout"
            }, function(orig, fix) {
                var handler = function(event) {
                    jQuery.event.simulate(fix, event.target, jQuery.event.fix(event), true);
                };
                jQuery.event.special[fix] = {
                    setup: function() {
                        var doc = this.ownerDocument || this,
                            attaches = data_priv.access(doc, fix);
                        if (!attaches) {
                            doc.addEventListener(orig, handler, true);
                        }
                        data_priv.access(doc, fix, (attaches || 0) + 1);
                    },
                    teardown: function() {
                        var doc = this.ownerDocument || this,
                            attaches = data_priv.access(doc, fix) - 1;
                        if (!attaches) {
                            doc.removeEventListener(orig, handler, true);
                            data_priv.remove(doc, fix);
                        } else {
                            data_priv.access(doc, fix, attaches);
                        }
                    }
                };
            });
        }
        jQuery.fn.extend({
            on: function(types, selector, data, fn, one) {
                var origFn, type;
                if (typeof types === "object") {
                    if (typeof selector !== "string") {
                        data = data || selector;
                        selector = undefined;
                    }
                    for (type in types) {
                        this.on(type, selector, data, types[type], one);
                    }
                    return this;
                }
                if (data == null && fn == null) {
                    fn = selector;
                    data = selector = undefined;
                } else if (fn == null) {
                    if (typeof selector === "string") {
                        fn = data;
                        data = undefined;
                    } else {
                        fn = data;
                        data = selector;
                        selector = undefined;
                    }
                }
                if (fn === false) {
                    fn = returnFalse;
                } else if (!fn) {
                    return this;
                }
                if (one === 1) {
                    origFn = fn;
                    fn = function(event) {
                        jQuery().off(event);
                        return origFn.apply(this, arguments);
                    };
                    fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);
                }
                return this.each(function() {
                    jQuery.event.add(this, types, fn, data, selector);
                });
            },
            one: function(types, selector, data, fn) {
                return this.on(types, selector, data, fn, 1);
            },
            off: function(types, selector, fn) {
                var handleObj, type;
                if (types && types.preventDefault && types.handleObj) {
                    handleObj = types.handleObj;
                    jQuery(types.delegateTarget).off(
                        handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
                        handleObj.selector,
                        handleObj.handler
                    );
                    return this;
                }
                if (typeof types === "object") {
                    for (type in types) {
                        this.off(type, selector, types[type]);
                    }
                    return this;
                }
                if (selector === false || typeof selector === "function") {
                    fn = selector;
                    selector = undefined;
                }
                if (fn === false) {
                    fn = returnFalse;
                }
                return this.each(function() {
                    jQuery.event.remove(this, types, fn, selector);
                });
            },
            trigger: function(type, data) {
                return this.each(function() {
                    jQuery.event.trigger(type, data, this);
                });
            },
            triggerHandler: function(type, data) {
                var elem = this[0];
                if (elem) {
                    return jQuery.event.trigger(type, data, elem, true);
                }
            }
        });
        var
            rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
            rtagName = /<([\w:]+)/,
            rhtml = /<|&#?\w+;/,
            rnoInnerhtml = /<(?:script|style|link)/i,
            rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
            rscriptType = /^$|\/(?:java|ecma)script/i,
            rscriptTypeMasked = /^true\/(.*)/,
            rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
            wrapMap = {
                option: [1, "<select multiple='multiple'>", "</select>"],
                thead: [1, "<table>", "</table>"],
                col: [2, "<table><colgroup>", "</colgroup></table>"],
                tr: [2, "<table><tbody>", "</tbody></table>"],
                td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
                _default: [0, "", ""]
            };
        wrapMap.optgroup = wrapMap.option;
        wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
        wrapMap.th = wrapMap.td;
    
        function manipulationTarget(elem, content) {
            return jQuery.nodeName(elem, "table") &&
                jQuery.nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr") ?
                elem.getElementsByTagName("tbody")[0] ||
                elem.appendChild(elem.ownerDocument.createElement("tbody")) :
                elem;
        }
    
        function disableScript(elem) {
            elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
            return elem;
        }
    
        function restoreScript(elem) {
            var match = rscriptTypeMasked.exec(elem.type);
            if (match) {
                elem.type = match[1];
            } else {
                elem.removeAttribute("type");
            }
            return elem;
        }
    
        function setGlobalEval(elems, refElements) {
            var i = 0,
                l = elems.length;
            for (; i < l; i++) {
                data_priv.set(
                    elems[i], "globalEval", !refElements || data_priv.get(refElements[i], "globalEval")
                );
            }
        }
    
        function cloneCopyEvent(src, dest) {
            var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
            if (dest.nodeType !== 1) {
                return;
            }
            if (data_priv.hasData(src)) {
                pdataOld = data_priv.access(src);
                pdataCur = data_priv.set(dest, pdataOld);
                events = pdataOld.events;
                if (events) {
                    delete pdataCur.handle;
                    pdataCur.events = {};
                    for (type in events) {
                        for (i = 0, l = events[type].length; i < l; i++) {
                            jQuery.event.add(dest, type, events[type][i]);
                        }
                    }
                }
            }
            if (data_user.hasData(src)) {
                udataOld = data_user.access(src);
                udataCur = jQuery.extend({}, udataOld);
                data_user.set(dest, udataCur);
            }
        }
    
        function getAll(context, tag) {
            var ret = context.getElementsByTagName ? context.getElementsByTagName(tag || "*") :
                context.querySelectorAll ? context.querySelectorAll(tag || "*") : [];
            return tag === undefined || tag && jQuery.nodeName(context, tag) ?
                jQuery.merge([context], ret) :
                ret;
        }
    
        function fixInput(src, dest) {
            var nodeName = dest.nodeName.toLowerCase();
            if (nodeName === "input" && rcheckableType.test(src.type)) {
                dest.checked = src.checked;
            } else if (nodeName === "input" || nodeName === "textarea") {
                dest.defaultValue = src.defaultValue;
            }
        }
        jQuery.extend({
            clone: function(elem, dataAndEvents, deepDataAndEvents) {
                var i, l, srcElements, destElements,
                    clone = elem.cloneNode(true),
                    inPage = jQuery.contains(elem.ownerDocument, elem);
                if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) &&
                    !jQuery.isXMLDoc(elem)) {
                    destElements = getAll(clone);
                    srcElements = getAll(elem);
                    for (i = 0, l = srcElements.length; i < l; i++) {
                        fixInput(srcElements[i], destElements[i]);
                    }
                }
                if (dataAndEvents) {
                    if (deepDataAndEvents) {
                        srcElements = srcElements || getAll(elem);
                        destElements = destElements || getAll(clone);
                        for (i = 0, l = srcElements.length; i < l; i++) {
                            cloneCopyEvent(srcElements[i], destElements[i]);
                        }
                    } else {
                        cloneCopyEvent(elem, clone);
                    }
                }
                destElements = getAll(clone, "script");
                if (destElements.length > 0) {
                    setGlobalEval(destElements, !inPage && getAll(elem, "script"));
                }
                return clone;
            },
            buildFragment: function(elems, context, scripts, selection) {
                var elem, tmp, tag, wrap, contains, j,
                    fragment = context.createDocumentFragment(),
                    nodes = [],
                    i = 0,
                    l = elems.length;
                for (; i < l; i++) {
                    elem = elems[i];
                    if (elem || elem === 0) {
                        if (jQuery.type(elem) === "object") {
                            jQuery.merge(nodes, elem.nodeType ? [elem] : elem);
                        } else if (!rhtml.test(elem)) {
                            nodes.push(context.createTextNode(elem));
                        } else {
                            tmp = tmp || fragment.appendChild(context.createElement("div"));
                            tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase();
                            wrap = wrapMap[tag] || wrapMap._default;
                            tmp.innerHTML = wrap[1] + elem.replace(rxhtmlTag, "<$1></$2>") + wrap[2];
                            j = wrap[0];
                            while (j--) {
                                tmp = tmp.lastChild;
                            }
                            jQuery.merge(nodes, tmp.childNodes);
                            tmp = fragment.firstChild;
                            tmp.textContent = "";
                        }
                    }
                }
                fragment.textContent = "";
                i = 0;
                while ((elem = nodes[i++])) {
                    if (selection && jQuery.inArray(elem, selection) !== -1) {
                        continue;
                    }
                    contains = jQuery.contains(elem.ownerDocument, elem);
                    tmp = getAll(fragment.appendChild(elem), "script");
                    if (contains) {
                        setGlobalEval(tmp);
                    }
                    if (scripts) {
                        j = 0;
                        while ((elem = tmp[j++])) {
                            if (rscriptType.test(elem.type || "")) {
                                scripts.push(elem);
                            }
                        }
                    }
                }
                return fragment;
            },
            cleanData: function(elems) {
                var data, elem, type, key,
                    special = jQuery.event.special,
                    i = 0;
                for (;
                    (elem = elems[i]) !== undefined; i++) {
                    if (jQuery.acceptData(elem)) {
                        key = elem[data_priv.expando];
                        if (key && (data = data_priv.cache[key])) {
                            if (data.events) {
                                for (type in data.events) {
                                    if (special[type]) {
                                        jQuery.event.remove(elem, type);
                                    } else {
                                        jQuery.removeEvent(elem, type, data.handle);
                                    }
                                }
                            }
                            if (data_priv.cache[key]) {
                                delete data_priv.cache[key];
                            }
                        }
                    }
                    delete data_user.cache[elem[data_user.expando]];
                }
            }
        });
        jQuery.fn.extend({
            text: function(value) {
                return access(this, function(value) {
                    return value === undefined ?
                        jQuery.text(this) :
                        this.empty().each(function() {
                            if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
                                this.textContent = value;
                            }
                        });
                }, null, value, arguments.length);
            },
            append: function() {
                return this.domManip(arguments, function(elem) {
                    if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
                        var target = manipulationTarget(this, elem);
                        target.appendChild(elem);
                    }
                });
            },
            prepend: function() {
                return this.domManip(arguments, function(elem) {
                    if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
                        var target = manipulationTarget(this, elem);
                        target.insertBefore(elem, target.firstChild);
                    }
                });
            },
            before: function() {
                return this.domManip(arguments, function(elem) {
                    if (this.parentNode) {
                        this.parentNode.insertBefore(elem, this);
                    }
                });
            },
            after: function() {
                return this.domManip(arguments, function(elem) {
                    if (this.parentNode) {
                        this.parentNode.insertBefore(elem, this.nextSibling);
                    }
                });
            },
            remove: function(selector, keepData) {
                var elem,
                    elems = selector ? jQuery.filter(selector, this) : this,
                    i = 0;
                for (;
                    (elem = elems[i]) != null; i++) {
                    if (!keepData && elem.nodeType === 1) {
                        jQuery.cleanData(getAll(elem));
                    }
                    if (elem.parentNode) {
                        if (keepData && jQuery.contains(elem.ownerDocument, elem)) {
                            setGlobalEval(getAll(elem, "script"));
                        }
                        elem.parentNode.removeChild(elem);
                    }
                }
                return this;
            },
            empty: function() {
                var elem,
                    i = 0;
                for (;
                    (elem = this[i]) != null; i++) {
                    if (elem.nodeType === 1) {
                        jQuery.cleanData(getAll(elem, false));
                        elem.textContent = "";
                    }
                }
                return this;
            },
            clone: function(dataAndEvents, deepDataAndEvents) {
                dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
                deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
                return this.map(function() {
                    return jQuery.clone(this, dataAndEvents, deepDataAndEvents);
                });
            },
            html: function(value) {
                return access(this, function(value) {
                    var elem = this[0] || {},
                        i = 0,
                        l = this.length;
                    if (value === undefined && elem.nodeType === 1) {
                        return elem.innerHTML;
                    }
                    if (typeof value === "string" && !rnoInnerhtml.test(value) &&
                        !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) {
                        value = value.replace(rxhtmlTag, "<$1></$2>");
                        try {
                            for (; i < l; i++) {
                                elem = this[i] || {};
                                if (elem.nodeType === 1) {
                                    jQuery.cleanData(getAll(elem, false));
                                    elem.innerHTML = value;
                                }
                            }
                            elem = 0;
                        } catch (e) {}
                    }
                    if (elem) {
                        this.empty().append(value);
                    }
                }, null, value, arguments.length);
            },
            replaceWith: function() {
                var arg = arguments[0];
                this.domManip(arguments, function(elem) {
                    arg = this.parentNode;
                    jQuery.cleanData(getAll(this));
                    if (arg) {
                        arg.replaceChild(elem, this);
                    }
                });
                return arg && (arg.length || arg.nodeType) ? this : this.remove();
            },
            detach: function(selector) {
                return this.remove(selector, true);
            },
            domManip: function(args, callback) {
                args = concat.apply([], args);
                var fragment, first, scripts, hasScripts, node, doc,
                    i = 0,
                    l = this.length,
                    set = this,
                    iNoClone = l - 1,
                    value = args[0],
                    isFunction = jQuery.isFunction(value);
                if (isFunction ||
                    (l > 1 && typeof value === "string" &&
                        !support.checkClone && rchecked.test(value))) {
                    return this.each(function(index) {
                        var self = set.eq(index);
                        if (isFunction) {
                            args[0] = value.call(this, index, self.html());
                        }
                        self.domManip(args, callback);
                    });
                }
                if (l) {
                    fragment = jQuery.buildFragment(args, this[0].ownerDocument, false, this);
                    first = fragment.firstChild;
                    if (fragment.childNodes.length === 1) {
                        fragment = first;
                    }
                    if (first) {
                        scripts = jQuery.map(getAll(fragment, "script"), disableScript);
                        hasScripts = scripts.length;
                        for (; i < l; i++) {
                            node = fragment;
                            if (i !== iNoClone) {
                                node = jQuery.clone(node, true, true);
                                if (hasScripts) {
                                    jQuery.merge(scripts, getAll(node, "script"));
                                }
                            }
                            callback.call(this[i], node, i);
                        }
                        if (hasScripts) {
                            doc = scripts[scripts.length - 1].ownerDocument;
                            jQuery.map(scripts, restoreScript);
                            for (i = 0; i < hasScripts; i++) {
                                node = scripts[i];
                                if (rscriptType.test(node.type || "") &&
                                    !data_priv.access(node, "globalEval") && jQuery.contains(doc, node)) {
                                    if (node.src) {
                                        if (jQuery._evalUrl) {
                                            jQuery._evalUrl(node.src);
                                        }
                                    } else {
                                        jQuery.globalEval(node.textContent.replace(rcleanScript, ""));
                                    }
                                }
                            }
                        }
                    }
                }
                return this;
            }
        });
        jQuery.each({
            appendTo: "append",
            prependTo: "prepend",
            insertBefore: "before",
            insertAfter: "after",
            replaceAll: "replaceWith"
        }, function(name, original) {
            jQuery.fn[name] = function(selector) {
                var elems,
                    ret = [],
                    insert = jQuery(selector),
                    last = insert.length - 1,
                    i = 0;
                for (; i <= last; i++) {
                    elems = i === last ? this : this.clone(true);
                    jQuery(insert[i])[original](elems);
                    push.apply(ret, elems.get());
                }
                return this.pushStack(ret);
            };
        });
        var iframe,
            elemdisplay = {};
    
        function actualDisplay(name, doc) {
            var style,
                elem = jQuery(doc.createElement(name)).appendTo(doc.body),
                display = window.getDefaultComputedStyle && (style = window.getDefaultComputedStyle(elem[0])) ?
                style.display : jQuery.css(elem[0], "display");
            elem.detach();
            return display;
        }
    
        function defaultDisplay(nodeName) {
            var doc = document,
                display = elemdisplay[nodeName];
            if (!display) {
                display = actualDisplay(nodeName, doc);
                if (display === "none" || !display) {
                    iframe = (iframe || jQuery("<iframe frameborder='0' width='0' height='0'/>")).appendTo(doc.documentElement);
                    doc = iframe[0].contentDocument;
                    doc.write();
                    doc.close();
                    display = actualDisplay(nodeName, doc);
                    iframe.detach();
                }
                elemdisplay[nodeName] = display;
            }
            return display;
        }
        var rmargin = (/^margin/);
        var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i");
        var getStyles = function(elem) {
            if (elem.ownerDocument.defaultView.opener) {
                return elem.ownerDocument.defaultView.getComputedStyle(elem, null);
            }
            return window.getComputedStyle(elem, null);
        };
    
        function curCSS(elem, name, computed) {
            var width, minWidth, maxWidth, ret,
                style = elem.style;
            computed = computed || getStyles(elem);
            if (computed) {
                ret = computed.getPropertyValue(name) || computed[name];
            }
            if (computed) {
                if (ret === "" && !jQuery.contains(elem.ownerDocument, elem)) {
                    ret = jQuery.style(elem, name);
                }
                if (rnumnonpx.test(ret) && rmargin.test(name)) {
                    width = style.width;
                    minWidth = style.minWidth;
                    maxWidth = style.maxWidth;
                    style.minWidth = style.maxWidth = style.width = ret;
                    ret = computed.width;
                    style.width = width;
                    style.minWidth = minWidth;
                    style.maxWidth = maxWidth;
                }
            }
            return ret !== undefined ?
                ret + "" :
                ret;
        }
    
        function addGetHookIf(conditionFn, hookFn) {
            return {
                get: function() {
                    if (conditionFn()) {
                        delete this.get;
                        return;
                    }
                    return (this.get = hookFn).apply(this, arguments);
                }
            };
        }
        (function() {
            var pixelPositionVal, boxSizingReliableVal,
                docElem = document.documentElement,
                container = document.createElement("div"),
                div = document.createElement("div");
            if (!div.style) {
                return;
            }
            div.style.backgroundClip = "content-box";
            div.cloneNode(true).style.backgroundClip = "";
            support.clearCloneStyle = div.style.backgroundClip === "content-box";
            container.style.cssText = "border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;" +
                "position:absolute";
            container.appendChild(div);
    
            function computePixelPositionAndBoxSizingReliable() {
                div.style.cssText =
                    "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" +
                    "box-sizing:border-box;display:block;margin-top:1%;top:1%;" +
                    "border:1px;padding:1px;width:4px;position:absolute";
                div.innerHTML = "";
                docElem.appendChild(container);
                var divStyle = window.getComputedStyle(div, null);
                pixelPositionVal = divStyle.top !== "1%";
                boxSizingReliableVal = divStyle.width === "4px";
                docElem.removeChild(container);
            }
            if (window.getComputedStyle) {
                jQuery.extend(support, {
                    pixelPosition: function() {
                        computePixelPositionAndBoxSizingReliable();
                        return pixelPositionVal;
                    },
                    boxSizingReliable: function() {
                        if (boxSizingReliableVal == null) {
                            computePixelPositionAndBoxSizingReliable();
                        }
                        return boxSizingReliableVal;
                    },
                    reliableMarginRight: function() {
                        var ret,
                            marginDiv = div.appendChild(document.createElement("div"));
                        marginDiv.style.cssText = div.style.cssText =
                            "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
                            "box-sizing:content-box;display:block;margin:0;border:0;padding:0";
                        marginDiv.style.marginRight = marginDiv.style.width = "0";
                        div.style.width = "1px";
                        docElem.appendChild(container);
                        ret = !parseFloat(window.getComputedStyle(marginDiv, null).marginRight);
                        docElem.removeChild(container);
                        div.removeChild(marginDiv);
                        return ret;
                    }
                });
            }
        })();
        jQuery.swap = function(elem, options, callback, args) {
            var ret, name,
                old = {};
            for (name in options) {
                old[name] = elem.style[name];
                elem.style[name] = options[name];
            }
            ret = callback.apply(elem, args || []);
            for (name in options) {
                elem.style[name] = old[name];
            }
            return ret;
        };
        var
            rdisplayswap = /^(none|table(?!-c[ea]).+)/,
            rnumsplit = new RegExp("^(" + pnum + ")(.*)$", "i"),
            rrelNum = new RegExp("^([+-])=(" + pnum + ")", "i"),
            cssShow = {
                position: "absolute",
                visibility: "hidden",
                display: "block"
            },
            cssNormalTransform = {
                letterSpacing: "0",
                fontWeight: "400"
            },
            cssPrefixes = ["Webkit", "O", "Moz", "ms"];
    
        function vendorPropName(style, name) {
            if (name in style) {
                return name;
            }
            var capName = name[0].toUpperCase() + name.slice(1),
                origName = name,
                i = cssPrefixes.length;
            while (i--) {
                name = cssPrefixes[i] + capName;
                if (name in style) {
                    return name;
                }
            }
            return origName;
        }
    
        function setPositiveNumber(elem, value, subtract) {
            var matches = rnumsplit.exec(value);
            return matches ?
                Math.max(0, matches[1] - (subtract || 0)) + (matches[2] || "px") :
                value;
        }
    
        function augmentWidthOrHeight(elem, name, extra, isBorderBox, styles) {
            var i = extra === (isBorderBox ? "border" : "content") ?
                4 :
                name === "width" ? 1 : 0,
                val = 0;
            for (; i < 4; i += 2) {
                if (extra === "margin") {
                    val += jQuery.css(elem, extra + cssExpand[i], true, styles);
                }
                if (isBorderBox) {
                    if (extra === "content") {
                        val -= jQuery.css(elem, "padding" + cssExpand[i], true, styles);
                    }
                    if (extra !== "margin") {
                        val -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
                    }
                } else {
                    val += jQuery.css(elem, "padding" + cssExpand[i], true, styles);
                    if (extra !== "padding") {
                        val += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
                    }
                }
            }
            return val;
        }
    
        function getWidthOrHeight(elem, name, extra) {
            var valueIsBorderBox = true,
                val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
                styles = getStyles(elem),
                isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box";
            if (val <= 0 || val == null) {
                val = curCSS(elem, name, styles);
                if (val < 0 || val == null) {
                    val = elem.style[name];
                }
                if (rnumnonpx.test(val)) {
                    return val;
                }
                valueIsBorderBox = isBorderBox &&
                    (support.boxSizingReliable() || val === elem.style[name]);
                val = parseFloat(val) || 0;
            }
            return (val +
                augmentWidthOrHeight(
                    elem,
                    name,
                    extra || (isBorderBox ? "border" : "content"),
                    valueIsBorderBox,
                    styles
                )
            ) + "px";
        }
    
        function showHide(elements, show) {
            var display, elem, hidden,
                values = [],
                index = 0,
                length = elements.length;
            for (; index < length; index++) {
                elem = elements[index];
                if (!elem.style) {
                    continue;
                }
                values[index] = data_priv.get(elem, "olddisplay");
                display = elem.style.display;
                if (show) {
                    if (!values[index] && display === "none") {
                        elem.style.display = "";
                    }
                    if (elem.style.display === "" && isHidden(elem)) {
                        values[index] = data_priv.access(elem, "olddisplay", defaultDisplay(elem.nodeName));
                    }
                } else {
                    hidden = isHidden(elem);
                    if (display !== "none" || !hidden) {
                        data_priv.set(elem, "olddisplay", hidden ? display : jQuery.css(elem, "display"));
                    }
                }
            }
            for (index = 0; index < length; index++) {
                elem = elements[index];
                if (!elem.style) {
                    continue;
                }
                if (!show || elem.style.display === "none" || elem.style.display === "") {
                    elem.style.display = show ? values[index] || "" : "none";
                }
            }
            return elements;
        }
        jQuery.extend({
            cssHooks: {
                opacity: {
                    get: function(elem, computed) {
                        if (computed) {
                            var ret = curCSS(elem, "opacity");
                            return ret === "" ? "1" : ret;
                        }
                    }
                }
            },
            cssNumber: {
                "columnCount": true,
                "fillOpacity": true,
                "flexGrow": true,
                "flexShrink": true,
                "fontWeight": true,
                "lineHeight": true,
                "opacity": true,
                "order": true,
                "orphans": true,
                "widows": true,
                "zIndex": true,
                "zoom": true
            },
            cssProps: {
                "float": "cssFloat"
            },
            style: function(elem, name, value, extra) {
                if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) {
                    return;
                }
                var ret, type, hooks,
                    origName = jQuery.camelCase(name),
                    style = elem.style;
                name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(style, origName));
                hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];
                if (value !== undefined) {
                    type = typeof value;
                    if (type === "string" && (ret = rrelNum.exec(value))) {
                        value = (ret[1] + 1) * ret[2] + parseFloat(jQuery.css(elem, name));
                        type = "number";
                    }
                    if (value == null || value !== value) {
                        return;
                    }
                    if (type === "number" && !jQuery.cssNumber[origName]) {
                        value += "px";
                    }
                    if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) {
                        style[name] = "inherit";
                    }
                    if (!hooks || !("set" in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) {
                        style[name] = value;
                    }
                } else {
                    if (hooks && "get" in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) {
                        return ret;
                    }
                    return style[name];
                }
            },
            css: function(elem, name, extra, styles) {
                var val, num, hooks,
                    origName = jQuery.camelCase(name);
                name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(elem.style, origName));
                hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];
                if (hooks && "get" in hooks) {
                    val = hooks.get(elem, true, extra);
                }
                if (val === undefined) {
                    val = curCSS(elem, name, styles);
                }
                if (val === "normal" && name in cssNormalTransform) {
                    val = cssNormalTransform[name];
                }
                if (extra === "" || extra) {
                    num = parseFloat(val);
                    return extra === true || jQuery.isNumeric(num) ? num || 0 : val;
                }
                return val;
            }
        });
        jQuery.each(["height", "width"], function(i, name) {
            jQuery.cssHooks[name] = {
                get: function(elem, computed, extra) {
                    if (computed) {
                        return rdisplayswap.test(jQuery.css(elem, "display")) && elem.offsetWidth === 0 ?
                            jQuery.swap(elem, cssShow, function() {
                                return getWidthOrHeight(elem, name, extra);
                            }) :
                            getWidthOrHeight(elem, name, extra);
                    }
                },
                set: function(elem, value, extra) {
                    var styles = extra && getStyles(elem);
                    return setPositiveNumber(elem, value, extra ?
                        augmentWidthOrHeight(
                            elem,
                            name,
                            extra,
                            jQuery.css(elem, "boxSizing", false, styles) === "border-box",
                            styles
                        ) : 0
                    );
                }
            };
        });
        jQuery.cssHooks.marginRight = addGetHookIf(support.reliableMarginRight,
            function(elem, computed) {
                if (computed) {
                    return jQuery.swap(elem, {
                            "display": "inline-block"
                        },
                        curCSS, [elem, "marginRight"]);
                }
            }
        );
        jQuery.each({
            margin: "",
            padding: "",
            border: "Width"
        }, function(prefix, suffix) {
            jQuery.cssHooks[prefix + suffix] = {
                expand: function(value) {
                    var i = 0,
                        expanded = {},
                        parts = typeof value === "string" ? value.split(" ") : [value];
                    for (; i < 4; i++) {
                        expanded[prefix + cssExpand[i] + suffix] =
                            parts[i] || parts[i - 2] || parts[0];
                    }
                    return expanded;
                }
            };
            if (!rmargin.test(prefix)) {
                jQuery.cssHooks[prefix + suffix].set = setPositiveNumber;
            }
        });
        jQuery.fn.extend({
            css: function(name, value) {
                return access(this, function(elem, name, value) {
                    var styles, len,
                        map = {},
                        i = 0;
                    if (jQuery.isArray(name)) {
                        styles = getStyles(elem);
                        len = name.length;
                        for (; i < len; i++) {
                            map[name[i]] = jQuery.css(elem, name[i], false, styles);
                        }
                        return map;
                    }
                    return value !== undefined ?
                        jQuery.style(elem, name, value) :
                        jQuery.css(elem, name);
                }, name, value, arguments.length > 1);
            },
            show: function() {
                return showHide(this, true);
            },
            hide: function() {
                return showHide(this);
            },
            toggle: function(state) {
                if (typeof state === "boolean") {
                    return state ? this.show() : this.hide();
                }
                return this.each(function() {
                    if (isHidden(this)) {
                        jQuery(this).show();
                    } else {
                        jQuery(this).hide();
                    }
                });
            }
        });
    
        function Tween(elem, options, prop, end, easing) {
            return new Tween.prototype.init(elem, options, prop, end, easing);
        }
        jQuery.Tween = Tween;
        Tween.prototype = {
            constructor: Tween,
            init: function(elem, options, prop, end, easing, unit) {
                this.elem = elem;
                this.prop = prop;
                this.easing = easing || "swing";
                this.options = options;
                this.start = this.now = this.cur();
                this.end = end;
                this.unit = unit || (jQuery.cssNumber[prop] ? "" : "px");
            },
            cur: function() {
                var hooks = Tween.propHooks[this.prop];
                return hooks && hooks.get ?
                    hooks.get(this) :
                    Tween.propHooks._default.get(this);
            },
            run: function(percent) {
                var eased,
                    hooks = Tween.propHooks[this.prop];
                if (this.options.duration) {
                    this.pos = eased = jQuery.easing[this.easing](
                        percent, this.options.duration * percent, 0, 1, this.options.duration
                    );
                } else {
                    this.pos = eased = percent;
                }
                this.now = (this.end - this.start) * eased + this.start;
                if (this.options.step) {
                    this.options.step.call(this.elem, this.now, this);
                }
                if (hooks && hooks.set) {
                    hooks.set(this);
                } else {
                    Tween.propHooks._default.set(this);
                }
                return this;
            }
        };
        Tween.prototype.init.prototype = Tween.prototype;
        Tween.propHooks = {
            _default: {
                get: function(tween) {
                    var result;
                    if (tween.elem[tween.prop] != null &&
                        (!tween.elem.style || tween.elem.style[tween.prop] == null)) {
                        return tween.elem[tween.prop];
                    }
                    result = jQuery.css(tween.elem, tween.prop, "");
                    return !result || result === "auto" ? 0 : result;
                },
                set: function(tween) {
                    if (jQuery.fx.step[tween.prop]) {
                        jQuery.fx.step[tween.prop](tween);
                    } else if (tween.elem.style && (tween.elem.style[jQuery.cssProps[tween.prop]] != null || jQuery.cssHooks[tween.prop])) {
                        jQuery.style(tween.elem, tween.prop, tween.now + tween.unit);
                    } else {
                        tween.elem[tween.prop] = tween.now;
                    }
                }
            }
        };
        Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
            set: function(tween) {
                if (tween.elem.nodeType && tween.elem.parentNode) {
                    tween.elem[tween.prop] = tween.now;
                }
            }
        };
        jQuery.easing = {
            linear: function(p) {
                return p;
            },
            swing: function(p) {
                return 0.5 - Math.cos(p * Math.PI) / 2;
            }
        };
        jQuery.fx = Tween.prototype.init;
        jQuery.fx.step = {};
        var
            fxNow, timerId,
            rfxtypes = /^(?:toggle|show|hide)$/,
            rfxnum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i"),
            rrun = /queueHooks$/,
            animationPrefilters = [defaultPrefilter],
            tweeners = {
                "*": [function(prop, value) {
                    var tween = this.createTween(prop, value),
                        target = tween.cur(),
                        parts = rfxnum.exec(value),
                        unit = parts && parts[3] || (jQuery.cssNumber[prop] ? "" : "px"),
                        start = (jQuery.cssNumber[prop] || unit !== "px" && +target) &&
                        rfxnum.exec(jQuery.css(tween.elem, prop)),
                        scale = 1,
                        maxIterations = 20;
                    if (start && start[3] !== unit) {
                        unit = unit || start[3];
                        parts = parts || [];
                        start = +target || 1;
                        do {
                            scale = scale || ".5";
                            start = start / scale;
                            jQuery.style(tween.elem, prop, start + unit);
                        } while (scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations);
                    }
                    if (parts) {
                        start = tween.start = +start || +target || 0;
                        tween.unit = unit;
                        tween.end = parts[1] ?
                            start + (parts[1] + 1) * parts[2] :
                            +parts[2];
                    }
                    return tween;
                }]
            };
    
        function createFxNow() {
            setTimeout(function() {
                fxNow = undefined;
            });
            return (fxNow = jQuery.now());
        }
    
        function genFx(type, includeWidth) {
            var which,
                i = 0,
                attrs = {
                    height: type
                };
            includeWidth = includeWidth ? 1 : 0;
            for (; i < 4; i += 2 - includeWidth) {
                which = cssExpand[i];
                attrs["margin" + which] = attrs["padding" + which] = type;
            }
            if (includeWidth) {
                attrs.opacity = attrs.width = type;
            }
            return attrs;
        }
    
        function createTween(value, prop, animation) {
            var tween,
                collection = (tweeners[prop] || []).concat(tweeners["*"]),
                index = 0,
                length = collection.length;
            for (; index < length; index++) {
                if ((tween = collection[index].call(animation, prop, value))) {
                    return tween;
                }
            }
        }
    
        function defaultPrefilter(elem, props, opts) {
            var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
                anim = this,
                orig = {},
                style = elem.style,
                hidden = elem.nodeType && isHidden(elem),
                dataShow = data_priv.get(elem, "fxshow");
            if (!opts.queue) {
                hooks = jQuery._queueHooks(elem, "fx");
                if (hooks.unqueued == null) {
                    hooks.unqueued = 0;
                    oldfire = hooks.empty.fire;
                    hooks.empty.fire = function() {
                        if (!hooks.unqueued) {
                            oldfire();
                        }
                    };
                }
                hooks.unqueued++;
                anim.always(function() {
                    anim.always(function() {
                        hooks.unqueued--;
                        if (!jQuery.queue(elem, "fx").length) {
                            hooks.empty.fire();
                        }
                    });
                });
            }
            if (elem.nodeType === 1 && ("height" in props || "width" in props)) {
                opts.overflow = [style.overflow, style.overflowX, style.overflowY];
                display = jQuery.css(elem, "display");
                checkDisplay = display === "none" ?
                    data_priv.get(elem, "olddisplay") || defaultDisplay(elem.nodeName) : display;
                if (checkDisplay === "inline" && jQuery.css(elem, "float") === "none") {
                    style.display = "inline-block";
                }
            }
            if (opts.overflow) {
                style.overflow = "hidden";
                anim.always(function() {
                    style.overflow = opts.overflow[0];
                    style.overflowX = opts.overflow[1];
                    style.overflowY = opts.overflow[2];
                });
            }
            for (prop in props) {
                value = props[prop];
                if (rfxtypes.exec(value)) {
                    delete props[prop];
                    toggle = toggle || value === "toggle";
                    if (value === (hidden ? "hide" : "show")) {
                        if (value === "show" && dataShow && dataShow[prop] !== undefined) {
                            hidden = true;
                        } else {
                            continue;
                        }
                    }
                    orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop);
                } else {
                    display = undefined;
                }
            }
            if (!jQuery.isEmptyObject(orig)) {
                if (dataShow) {
                    if ("hidden" in dataShow) {
                        hidden = dataShow.hidden;
                    }
                } else {
                    dataShow = data_priv.access(elem, "fxshow", {});
                }
                if (toggle) {
                    dataShow.hidden = !hidden;
                }
                if (hidden) {
                    jQuery(elem).show();
                } else {
                    anim.done(function() {
                        jQuery(elem).hide();
                    });
                }
                anim.done(function() {
                    var prop;
                    data_priv.remove(elem, "fxshow");
                    for (prop in orig) {
                        jQuery.style(elem, prop, orig[prop]);
                    }
                });
                for (prop in orig) {
                    tween = createTween(hidden ? dataShow[prop] : 0, prop, anim);
                    if (!(prop in dataShow)) {
                        dataShow[prop] = tween.start;
                        if (hidden) {
                            tween.end = tween.start;
                            tween.start = prop === "width" || prop === "height" ? 1 : 0;
                        }
                    }
                }
            } else if ((display === "none" ? defaultDisplay(elem.nodeName) : display) === "inline") {
                style.display = display;
            }
        }
    
        function propFilter(props, specialEasing) {
            var index, name, easing, value, hooks;
            for (index in props) {
                name = jQuery.camelCase(index);
                easing = specialEasing[name];
                value = props[index];
                if (jQuery.isArray(value)) {
                    easing = value[1];
                    value = props[index] = value[0];
                }
                if (index !== name) {
                    props[name] = value;
                    delete props[index];
                }
                hooks = jQuery.cssHooks[name];
                if (hooks && "expand" in hooks) {
                    value = hooks.expand(value);
                    delete props[name];
                    for (index in value) {
                        if (!(index in props)) {
                            props[index] = value[index];
                            specialEasing[index] = easing;
                        }
                    }
                } else {
                    specialEasing[name] = easing;
                }
            }
        }
    
        function Animation(elem, properties, options) {
            var result,
                stopped,
                index = 0,
                length = animationPrefilters.length,
                deferred = jQuery.Deferred().always(function() {
                    delete tick.elem;
                }),
                tick = function() {
                    if (stopped) {
                        return false;
                    }
                    var currentTime = fxNow || createFxNow(),
                        remaining = Math.max(0, animation.startTime + animation.duration - currentTime),
                        temp = remaining / animation.duration || 0,
                        percent = 1 - temp,
                        index = 0,
                        length = animation.tweens.length;
                    for (; index < length; index++) {
                        animation.tweens[index].run(percent);
                    }
                    deferred.notifyWith(elem, [animation, percent, remaining]);
                    if (percent < 1 && length) {
                        return remaining;
                    } else {
                        deferred.resolveWith(elem, [animation]);
                        return false;
                    }
                },
                animation = deferred.promise({
                    elem: elem,
                    props: jQuery.extend({}, properties),
                    opts: jQuery.extend(true, {
                        specialEasing: {}
                    }, options),
                    originalProperties: properties,
                    originalOptions: options,
                    startTime: fxNow || createFxNow(),
                    duration: options.duration,
                    tweens: [],
                    createTween: function(prop, end) {
                        var tween = jQuery.Tween(elem, animation.opts, prop, end,
                            animation.opts.specialEasing[prop] || animation.opts.easing);
                        animation.tweens.push(tween);
                        return tween;
                    },
                    stop: function(gotoEnd) {
                        var index = 0,
                            length = gotoEnd ? animation.tweens.length : 0;
                        if (stopped) {
                            return this;
                        }
                        stopped = true;
                        for (; index < length; index++) {
                            animation.tweens[index].run(1);
                        }
                        if (gotoEnd) {
                            deferred.resolveWith(elem, [animation, gotoEnd]);
                        } else {
                            deferred.rejectWith(elem, [animation, gotoEnd]);
                        }
                        return this;
                    }
                }),
                props = animation.props;
            propFilter(props, animation.opts.specialEasing);
            for (; index < length; index++) {
                result = animationPrefilters[index].call(animation, elem, props, animation.opts);
                if (result) {
                    return result;
                }
            }
            jQuery.map(props, createTween, animation);
            if (jQuery.isFunction(animation.opts.start)) {
                animation.opts.start.call(elem, animation);
            }
            jQuery.fx.timer(
                jQuery.extend(tick, {
                    elem: elem,
                    anim: animation,
                    queue: animation.opts.queue
                })
            );
            return animation.progress(animation.opts.progress)
                .done(animation.opts.done, animation.opts.complete)
                .fail(animation.opts.fail)
                .always(animation.opts.always);
        }
        jQuery.Animation = jQuery.extend(Animation, {
            tweener: function(props, callback) {
                if (jQuery.isFunction(props)) {
                    callback = props;
                    props = ["*"];
                } else {
                    props = props.split(" ");
                }
                var prop,
                    index = 0,
                    length = props.length;
                for (; index < length; index++) {
                    prop = props[index];
                    tweeners[prop] = tweeners[prop] || [];
                    tweeners[prop].unshift(callback);
                }
            },
            prefilter: function(callback, prepend) {
                if (prepend) {
                    animationPrefilters.unshift(callback);
                } else {
                    animationPrefilters.push(callback);
                }
            }
        });
        jQuery.speed = function(speed, easing, fn) {
            var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
                complete: fn || !fn && easing ||
                    jQuery.isFunction(speed) && speed,
                duration: speed,
                easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
            };
            opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
                opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
            if (opt.queue == null || opt.queue === true) {
                opt.queue = "fx";
            }
            opt.old = opt.complete;
            opt.complete = function() {
                if (jQuery.isFunction(opt.old)) {
                    opt.old.call(this);
                }
                if (opt.queue) {
                    jQuery.dequeue(this, opt.queue);
                }
            };
            return opt;
        };
        jQuery.fn.extend({
            fadeTo: function(speed, to, easing, callback) {
                return this.filter(isHidden).css("opacity", 0).show()
                    .end().animate({
                        opacity: to
                    }, speed, easing, callback);
            },
            animate: function(prop, speed, easing, callback) {
                var empty = jQuery.isEmptyObject(prop),
                    optall = jQuery.speed(speed, easing, callback),
                    doAnimation = function() {
                        var anim = Animation(this, jQuery.extend({}, prop), optall);
                        if (empty || data_priv.get(this, "finish")) {
                            anim.stop(true);
                        }
                    };
                doAnimation.finish = doAnimation;
                return empty || optall.queue === false ?
                    this.each(doAnimation) :
                    this.queue(optall.queue, doAnimation);
            },
            stop: function(type, clearQueue, gotoEnd) {
                var stopQueue = function(hooks) {
                    var stop = hooks.stop;
                    delete hooks.stop;
                    stop(gotoEnd);
                };
                if (typeof type !== "string") {
                    gotoEnd = clearQueue;
                    clearQueue = type;
                    type = undefined;
                }
                if (clearQueue && type !== false) {
                    this.queue(type || "fx", []);
                }
                return this.each(function() {
                    var dequeue = true,
                        index = type != null && type + "queueHooks",
                        timers = jQuery.timers,
                        data = data_priv.get(this);
                    if (index) {
                        if (data[index] && data[index].stop) {
                            stopQueue(data[index]);
                        }
                    } else {
                        for (index in data) {
                            if (data[index] && data[index].stop && rrun.test(index)) {
                                stopQueue(data[index]);
                            }
                        }
                    }
                    for (index = timers.length; index--;) {
                        if (timers[index].elem === this && (type == null || timers[index].queue === type)) {
                            timers[index].anim.stop(gotoEnd);
                            dequeue = false;
                            timers.splice(index, 1);
                        }
                    }
                    if (dequeue || !gotoEnd) {
                        jQuery.dequeue(this, type);
                    }
                });
            },
            finish: function(type) {
                if (type !== false) {
                    type = type || "fx";
                }
                return this.each(function() {
                    var index,
                        data = data_priv.get(this),
                        queue = data[type + "queue"],
                        hooks = data[type + "queueHooks"],
                        timers = jQuery.timers,
                        length = queue ? queue.length : 0;
                    data.finish = true;
                    jQuery.queue(this, type, []);
                    if (hooks && hooks.stop) {
                        hooks.stop.call(this, true);
                    }
                    for (index = timers.length; index--;) {
                        if (timers[index].elem === this && timers[index].queue === type) {
                            timers[index].anim.stop(true);
                            timers.splice(index, 1);
                        }
                    }
                    for (index = 0; index < length; index++) {
                        if (queue[index] && queue[index].finish) {
                            queue[index].finish.call(this);
                        }
                    }
                    delete data.finish;
                });
            }
        });
        jQuery.each(["toggle", "show", "hide"], function(i, name) {
            var cssFn = jQuery.fn[name];
            jQuery.fn[name] = function(speed, easing, callback) {
                return speed == null || typeof speed === "boolean" ?
                    cssFn.apply(this, arguments) :
                    this.animate(genFx(name, true), speed, easing, callback);
            };
        });
        jQuery.each({
            slideDown: genFx("show"),
            slideUp: genFx("hide"),
            slideToggle: genFx("toggle"),
            fadeIn: {
                opacity: "show"
            },
            fadeOut: {
                opacity: "hide"
            },
            fadeToggle: {
                opacity: "toggle"
            }
        }, function(name, props) {
            jQuery.fn[name] = function(speed, easing, callback) {
                return this.animate(props, speed, easing, callback);
            };
        });
        jQuery.timers = [];
        jQuery.fx.tick = function() {
            var timer,
                i = 0,
                timers = jQuery.timers;
            fxNow = jQuery.now();
            for (; i < timers.length; i++) {
                timer = timers[i];
                if (!timer() && timers[i] === timer) {
                    timers.splice(i--, 1);
                }
            }
            if (!timers.length) {
                jQuery.fx.stop();
            }
            fxNow = undefined;
        };
        jQuery.fx.timer = function(timer) {
            jQuery.timers.push(timer);
            if (timer()) {
                jQuery.fx.start();
            } else {
                jQuery.timers.pop();
            }
        };
        jQuery.fx.interval = 13;
        jQuery.fx.start = function() {
            if (!timerId) {
                timerId = setInterval(jQuery.fx.tick, jQuery.fx.interval);
            }
        };
        jQuery.fx.stop = function() {
            clearInterval(timerId);
            timerId = null;
        };
        jQuery.fx.speeds = {
            slow: 600,
            fast: 200,
            _default: 400
        };
        jQuery.fn.delay = function(time, type) {
            time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
            type = type || "fx";
            return this.queue(type, function(next, hooks) {
                var timeout = setTimeout(next, time);
                hooks.stop = function() {
                    clearTimeout(timeout);
                };
            });
        };
        (function() {
            var input = document.createElement("input"),
                select = document.createElement("select"),
                opt = select.appendChild(document.createElement("option"));
            input.type = "checkbox";
            support.checkOn = input.value !== "";
            support.optSelected = opt.selected;
            select.disabled = true;
            support.optDisabled = !opt.disabled;
            input = document.createElement("input");
            input.value = "t";
            input.type = "radio";
            support.radioValue = input.value === "t";
        })();
        var nodeHook, boolHook,
            attrHandle = jQuery.expr.attrHandle;
        jQuery.fn.extend({
            attr: function(name, value) {
                return access(this, jQuery.attr, name, value, arguments.length > 1);
            },
            removeAttr: function(name) {
                return this.each(function() {
                    jQuery.removeAttr(this, name);
                });
            }
        });
        jQuery.extend({
            attr: function(elem, name, value) {
                var hooks, ret,
                    nType = elem.nodeType;
                if (!elem || nType === 3 || nType === 8 || nType === 2) {
                    return;
                }
                if (typeof elem.getAttribute === strundefined) {
                    return jQuery.prop(elem, name, value);
                }
                if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
                    name = name.toLowerCase();
                    hooks = jQuery.attrHooks[name] ||
                        (jQuery.expr.match.bool.test(name) ? boolHook : nodeHook);
                }
                if (value !== undefined) {
                    if (value === null) {
                        jQuery.removeAttr(elem, name);
                    } else if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) {
                        return ret;
                    } else {
                        elem.setAttribute(name, value + "");
                        return value;
                    }
                } else if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
                    return ret;
                } else {
                    ret = jQuery.find.attr(elem, name);
                    return ret == null ?
                        undefined :
                        ret;
                }
            },
            removeAttr: function(elem, value) {
                var name, propName,
                    i = 0,
                    attrNames = value && value.match(rnotwhite);
                if (attrNames && elem.nodeType === 1) {
                    while ((name = attrNames[i++])) {
                        propName = jQuery.propFix[name] || name;
                        if (jQuery.expr.match.bool.test(name)) {
                            elem[propName] = false;
                        }
                        elem.removeAttribute(name);
                    }
                }
            },
            attrHooks: {
                type: {
                    set: function(elem, value) {
                        if (!support.radioValue && value === "radio" &&
                            jQuery.nodeName(elem, "input")) {
                            var val = elem.value;
                            elem.setAttribute("type", value);
                            if (val) {
                                elem.value = val;
                            }
                            return value;
                        }
                    }
                }
            }
        });
        boolHook = {
            set: function(elem, value, name) {
                if (value === false) {
                    jQuery.removeAttr(elem, name);
                } else {
                    elem.setAttribute(name, name);
                }
                return name;
            }
        };
        jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function(i, name) {
            var getter = attrHandle[name] || jQuery.find.attr;
            attrHandle[name] = function(elem, name, isXML) {
                var ret, handle;
                if (!isXML) {
                    handle = attrHandle[name];
                    attrHandle[name] = ret;
                    ret = getter(elem, name, isXML) != null ?
                        name.toLowerCase() :
                        null;
                    attrHandle[name] = handle;
                }
                return ret;
            };
        });
        var rfocusable = /^(?:input|select|textarea|button)$/i;
        jQuery.fn.extend({
            prop: function(name, value) {
                return access(this, jQuery.prop, name, value, arguments.length > 1);
            },
            removeProp: function(name) {
                return this.each(function() {
                    delete this[jQuery.propFix[name] || name];
                });
            }
        });
        jQuery.extend({
            propFix: {
                "for": "htmlFor",
                "class": "className"
            },
            prop: function(elem, name, value) {
                var ret, hooks, notxml,
                    nType = elem.nodeType;
                if (!elem || nType === 3 || nType === 8 || nType === 2) {
                    return;
                }
                notxml = nType !== 1 || !jQuery.isXMLDoc(elem);
                if (notxml) {
                    name = jQuery.propFix[name] || name;
                    hooks = jQuery.propHooks[name];
                }
                if (value !== undefined) {
                    return hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined ?
                        ret :
                        (elem[name] = value);
                } else {
                    return hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null ?
                        ret :
                        elem[name];
                }
            },
            propHooks: {
                tabIndex: {
                    get: function(elem) {
                        return elem.hasAttribute("tabindex") || rfocusable.test(elem.nodeName) || elem.href ?
                            elem.tabIndex :
                            -1;
                    }
                }
            }
        });
        if (!support.optSelected) {
            jQuery.propHooks.selected = {
                get: function(elem) {
                    var parent = elem.parentNode;
                    if (parent && parent.parentNode) {
                        parent.parentNode.selectedIndex;
                    }
                    return null;
                }
            };
        }
        jQuery.each([
            "tabIndex",
            "readOnly",
            "maxLength",
            "cellSpacing",
            "cellPadding",
            "rowSpan",
            "colSpan",
            "useMap",
            "frameBorder",
            "contentEditable"
        ], function() {
            jQuery.propFix[this.toLowerCase()] = this;
        });
        var rclass = /[\t\r\n\f]/g;
        jQuery.fn.extend({
            addClass: function(value) {
                var classes, elem, cur, clazz, j, finalValue,
                    proceed = typeof value === "string" && value,
                    i = 0,
                    len = this.length;
                if (jQuery.isFunction(value)) {
                    return this.each(function(j) {
                        jQuery(this).addClass(value.call(this, j, this.className));
                    });
                }
                if (proceed) {
                    classes = (value || "").match(rnotwhite) || [];
                    for (; i < len; i++) {
                        elem = this[i];
                        cur = elem.nodeType === 1 && (elem.className ?
                            (" " + elem.className + " ").replace(rclass, " ") :
                            " "
                        );
                        if (cur) {
                            j = 0;
                            while ((clazz = classes[j++])) {
                                if (cur.indexOf(" " + clazz + " ") < 0) {
                                    cur += clazz + " ";
                                }
                            }
                            finalValue = jQuery.trim(cur);
                            if (elem.className !== finalValue) {
                                elem.className = finalValue;
                            }
                        }
                    }
                }
                return this;
            },
            removeClass: function(value) {
                var classes, elem, cur, clazz, j, finalValue,
                    proceed = arguments.length === 0 || typeof value === "string" && value,
                    i = 0,
                    len = this.length;
                if (jQuery.isFunction(value)) {
                    return this.each(function(j) {
                        jQuery(this).removeClass(value.call(this, j, this.className));
                    });
                }
                if (proceed) {
                    classes = (value || "").match(rnotwhite) || [];
                    for (; i < len; i++) {
                        elem = this[i];
                        cur = elem.nodeType === 1 && (elem.className ?
                            (" " + elem.className + " ").replace(rclass, " ") :
                            ""
                        );
                        if (cur) {
                            j = 0;
                            while ((clazz = classes[j++])) {
                                while (cur.indexOf(" " + clazz + " ") >= 0) {
                                    cur = cur.replace(" " + clazz + " ", " ");
                                }
                            }
                            finalValue = value ? jQuery.trim(cur) : "";
                            if (elem.className !== finalValue) {
                                elem.className = finalValue;
                            }
                        }
                    }
                }
                return this;
            },
            toggleClass: function(value, stateVal) {
                var type = typeof value;
                if (typeof stateVal === "boolean" && type === "string") {
                    return stateVal ? this.addClass(value) : this.removeClass(value);
                }
                if (jQuery.isFunction(value)) {
                    return this.each(function(i) {
                        jQuery(this).toggleClass(value.call(this, i, this.className, stateVal), stateVal);
                    });
                }
                return this.each(function() {
                    if (type === "string") {
                        var className,
                            i = 0,
                            self = jQuery(this),
                            classNames = value.match(rnotwhite) || [];
                        while ((className = classNames[i++])) {
                            if (self.hasClass(className)) {
                                self.removeClass(className);
                            } else {
                                self.addClass(className);
                            }
                        }
                    } else if (type === strundefined || type === "boolean") {
                        if (this.className) {
                            data_priv.set(this, "__className__", this.className);
                        }
                        this.className = this.className || value === false ? "" : data_priv.get(this, "__className__") || "";
                    }
                });
            },
            hasClass: function(selector) {
                var className = " " + selector + " ",
                    i = 0,
                    l = this.length;
                for (; i < l; i++) {
                    if (this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf(className) >= 0) {
                        return true;
                    }
                }
                return false;
            }
        });
        var rreturn = /\r/g;
        jQuery.fn.extend({
            val: function(value) {
                var hooks, ret, isFunction,
                    elem = this[0];
                if (!arguments.length) {
                    if (elem) {
                        hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()];
                        if (hooks && "get" in hooks && (ret = hooks.get(elem, "value")) !== undefined) {
                            return ret;
                        }
                        ret = elem.value;
                        return typeof ret === "string" ?
                            ret.replace(rreturn, "") :
                            ret == null ? "" : ret;
                    }
                    return;
                }
                isFunction = jQuery.isFunction(value);
                return this.each(function(i) {
                    var val;
                    if (this.nodeType !== 1) {
                        return;
                    }
                    if (isFunction) {
                        val = value.call(this, i, jQuery(this).val());
                    } else {
                        val = value;
                    }
                    if (val == null) {
                        val = "";
                    } else if (typeof val === "number") {
                        val += "";
                    } else if (jQuery.isArray(val)) {
                        val = jQuery.map(val, function(value) {
                            return value == null ? "" : value + "";
                        });
                    }
                    hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()];
                    if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) {
                        this.value = val;
                    }
                });
            }
        });
        jQuery.extend({
            valHooks: {
                option: {
                    get: function(elem) {
                        var val = jQuery.find.attr(elem, "value");
                        return val != null ?
                            val :
                            jQuery.trim(jQuery.text(elem));
                    }
                },
                select: {
                    get: function(elem) {
                        var value, option,
                            options = elem.options,
                            index = elem.selectedIndex,
                            one = elem.type === "select-one" || index < 0,
                            values = one ? null : [],
                            max = one ? index + 1 : options.length,
                            i = index < 0 ?
                            max :
                            one ? index : 0;
                        for (; i < max; i++) {
                            option = options[i];
                            if ((option.selected || i === index) &&
                                (support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
                                (!option.parentNode.disabled || !jQuery.nodeName(option.parentNode, "optgroup"))) {
                                value = jQuery(option).val();
                                if (one) {
                                    return value;
                                }
                                values.push(value);
                            }
                        }
                        return values;
                    },
                    set: function(elem, value) {
                        var optionSet, option,
                            options = elem.options,
                            values = jQuery.makeArray(value),
                            i = options.length;
                        while (i--) {
                            option = options[i];
                            if ((option.selected = jQuery.inArray(option.value, values) >= 0)) {
                                optionSet = true;
                            }
                        }
                        if (!optionSet) {
                            elem.selectedIndex = -1;
                        }
                        return values;
                    }
                }
            }
        });
        jQuery.each(["radio", "checkbox"], function() {
            jQuery.valHooks[this] = {
                set: function(elem, value) {
                    if (jQuery.isArray(value)) {
                        return (elem.checked = jQuery.inArray(jQuery(elem).val(), value) >= 0);
                    }
                }
            };
            if (!support.checkOn) {
                jQuery.valHooks[this].get = function(elem) {
                    return elem.getAttribute("value") === null ? "on" : elem.value;
                };
            }
        });
        jQuery.each(("blur focus focusin focusout load resize scroll unload click dblclick " +
            "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
            "change select submit keydown keypress keyup error contextmenu").split(" "), function(i, name) {
            jQuery.fn[name] = function(data, fn) {
                return arguments.length > 0 ?
                    this.on(name, null, data, fn) :
                    this.trigger(name);
            };
        });
        jQuery.fn.extend({
            hover: function(fnOver, fnOut) {
                return this.mouseenter(fnOver).mouseleave(fnOut || fnOver);
            },
            bind: function(types, data, fn) {
                return this.on(types, null, data, fn);
            },
            unbind: function(types, fn) {
                return this.off(types, null, fn);
            },
            delegate: function(selector, types, data, fn) {
                return this.on(types, selector, data, fn);
            },
            undelegate: function(selector, types, fn) {
                return arguments.length === 1 ? this.off(selector, "**") : this.off(types, selector || "**", fn);
            }
        });
        var nonce = jQuery.now();
        var rquery = (/\?/);
        jQuery.parseJSON = function(data) {
            return JSON.parse(data + "");
        };
        jQuery.parseXML = function(data) {
            var xml, tmp;
            if (!data || typeof data !== "string") {
                return null;
            }
            try {
                tmp = new DOMParser();
                xml = tmp.parseFromString(data, "text/xml");
            } catch (e) {
                xml = undefined;
            }
            if (!xml || xml.getElementsByTagName("parsererror").length) {
                jQuery.error("Invalid XML: " + data);
            }
            return xml;
        };
        var
            rhash = /#.*$/,
            rts = /([?&])_=[^&]*/,
            rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
            rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
            rnoContent = /^(?:GET|HEAD)$/,
            rprotocol = /^\/\//,
            rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
            prefilters = {},
            transports = {},
            allTypes = "*/".concat("*"),
            ajaxLocation = window.location.href,
            ajaxLocParts = rurl.exec(ajaxLocation.toLowerCase()) || [];
    
        function addToPrefiltersOrTransports(structure) {
            return function(dataTypeExpression, func) {
                if (typeof dataTypeExpression !== "string") {
                    func = dataTypeExpression;
                    dataTypeExpression = "*";
                }
                var dataType,
                    i = 0,
                    dataTypes = dataTypeExpression.toLowerCase().match(rnotwhite) || [];
                if (jQuery.isFunction(func)) {
                    while ((dataType = dataTypes[i++])) {
                        if (dataType[0] === "+") {
                            dataType = dataType.slice(1) || "*";
                            (structure[dataType] = structure[dataType] || []).unshift(func);
                        } else {
                            (structure[dataType] = structure[dataType] || []).push(func);
                        }
                    }
                }
            };
        }
    
        function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) {
            var inspected = {},
                seekingTransport = (structure === transports);
    
            function inspect(dataType) {
                var selected;
                inspected[dataType] = true;
                jQuery.each(structure[dataType] || [], function(_, prefilterOrFactory) {
                    var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR);
                    if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) {
                        options.dataTypes.unshift(dataTypeOrTransport);
                        inspect(dataTypeOrTransport);
                        return false;
                    } else if (seekingTransport) {
                        return !(selected = dataTypeOrTransport);
                    }
                });
                return selected;
            }
            return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*");
        }
    
        function ajaxExtend(target, src) {
            var key, deep,
                flatOptions = jQuery.ajaxSettings.flatOptions || {};
            for (key in src) {
                if (src[key] !== undefined) {
                    (flatOptions[key] ? target : (deep || (deep = {})))[key] = src[key];
                }
            }
            if (deep) {
                jQuery.extend(true, target, deep);
            }
            return target;
        }
    
        function ajaxHandleResponses(s, jqXHR, responses) {
            var ct, type, finalDataType, firstDataType,
                contents = s.contents,
                dataTypes = s.dataTypes;
            while (dataTypes[0] === "*") {
                dataTypes.shift();
                if (ct === undefined) {
                    ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
                }
            }
            if (ct) {
                for (type in contents) {
                    if (contents[type] && contents[type].test(ct)) {
                        dataTypes.unshift(type);
                        break;
                    }
                }
            }
            if (dataTypes[0] in responses) {
                finalDataType = dataTypes[0];
            } else {
                for (type in responses) {
                    if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) {
                        finalDataType = type;
                        break;
                    }
                    if (!firstDataType) {
                        firstDataType = type;
                    }
                }
                finalDataType = finalDataType || firstDataType;
            }
            if (finalDataType) {
                if (finalDataType !== dataTypes[0]) {
                    dataTypes.unshift(finalDataType);
                }
                return responses[finalDataType];
            }
        }
    
        function ajaxConvert(s, response, jqXHR, isSuccess) {
            var conv2, current, conv, tmp, prev,
                converters = {},
                dataTypes = s.dataTypes.slice();
            if (dataTypes[1]) {
                for (conv in s.converters) {
                    converters[conv.toLowerCase()] = s.converters[conv];
                }
            }
            current = dataTypes.shift();
            while (current) {
                if (s.responseFields[current]) {
                    jqXHR[s.responseFields[current]] = response;
                }
                if (!prev && isSuccess && s.dataFilter) {
                    response = s.dataFilter(response, s.dataType);
                }
                prev = current;
                current = dataTypes.shift();
                if (current) {
                    if (current === "*") {
                        current = prev;
                    } else if (prev !== "*" && prev !== current) {
                        conv = converters[prev + " " + current] || converters["* " + current];
                        if (!conv) {
                            for (conv2 in converters) {
                                tmp = conv2.split(" ");
                                if (tmp[1] === current) {
                                    conv = converters[prev + " " + tmp[0]] ||
                                        converters["* " + tmp[0]];
                                    if (conv) {
                                        if (conv === true) {
                                            conv = converters[conv2];
                                        } else if (converters[conv2] !== true) {
                                            current = tmp[0];
                                            dataTypes.unshift(tmp[1]);
                                        }
                                        break;
                                    }
                                }
                            }
                        }
                        if (conv !== true) {
                            if (conv && s["throws"]) {
                                response = conv(response);
                            } else {
                                try {
                                    response = conv(response);
                                } catch (e) {
                                    return {
                                        state: "parsererror",
                                        error: conv ? e : "No conversion from " + prev + " to " + current
                                    };
                                }
                            }
                        }
                    }
                }
            }
            return {
                state: "success",
                data: response
            };
        }
        jQuery.extend({
            active: 0,
            lastModified: {},
            etag: {},
            ajaxSettings: {
                url: ajaxLocation,
                type: "GET",
                isLocal: rlocalProtocol.test(ajaxLocParts[1]),
                global: true,
                processData: true,
                async: true,
                contentType: "application/x-www-form-urlencoded; charset=UTF-8",
                accepts: {
                    "*": allTypes,
                    text: "text/plain",
                    html: "text/html",
                    xml: "application/xml, text/xml",
                    json: "application/json, text/javascript"
                },
                contents: {
                    xml: /xml/,
                    html: /html/,
                    json: /json/
                },
                responseFields: {
                    xml: "responseXML",
                    text: "responseText",
                    json: "responseJSON"
                },
                converters: {
                    "* text": String,
                    "text html": true,
                    "text json": jQuery.parseJSON,
                    "text xml": jQuery.parseXML
                },
                flatOptions: {
                    url: true,
                    context: true
                }
            },
            ajaxSetup: function(target, settings) {
                return settings ?
                    ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) :
                    ajaxExtend(jQuery.ajaxSettings, target);
            },
            ajaxPrefilter: addToPrefiltersOrTransports(prefilters),
            ajaxTransport: addToPrefiltersOrTransports(transports),
            ajax: function(url, options) {
                if (typeof url === "object") {
                    options = url;
                    url = undefined;
                }
                options = options || {};
                var transport,
                    cacheURL,
                    responseHeadersString,
                    responseHeaders,
                    timeoutTimer,
                    parts,
                    fireGlobals,
                    i,
                    s = jQuery.ajaxSetup({}, options),
                    callbackContext = s.context || s,
                    globalEventContext = s.context && (callbackContext.nodeType || callbackContext.jquery) ?
                    jQuery(callbackContext) :
                    jQuery.event,
                    deferred = jQuery.Deferred(),
                    completeDeferred = jQuery.Callbacks("once memory"),
                    statusCode = s.statusCode || {},
                    requestHeaders = {},
                    requestHeadersNames = {},
                    state = 0,
                    strAbort = "canceled",
                    jqXHR = {
                        readyState: 0,
                        getResponseHeader: function(key) {
                            var match;
                            if (state === 2) {
                                if (!responseHeaders) {
                                    responseHeaders = {};
                                    while ((match = rheaders.exec(responseHeadersString))) {
                                        responseHeaders[match[1].toLowerCase()] = match[2];
                                    }
                                }
                                match = responseHeaders[key.toLowerCase()];
                            }
                            return match == null ? null : match;
                        },
                        getAllResponseHeaders: function() {
                            return state === 2 ? responseHeadersString : null;
                        },
                        setRequestHeader: function(name, value) {
                            var lname = name.toLowerCase();
                            if (!state) {
                                name = requestHeadersNames[lname] = requestHeadersNames[lname] || name;
                                requestHeaders[name] = value;
                            }
                            return this;
                        },
                        overrideMimeType: function(type) {
                            if (!state) {
                                s.mimeType = type;
                            }
                            return this;
                        },
                        statusCode: function(map) {
                            var code;
                            if (map) {
                                if (state < 2) {
                                    for (code in map) {
                                        statusCode[code] = [statusCode[code], map[code]];
                                    }
                                } else {
                                    jqXHR.always(map[jqXHR.status]);
                                }
                            }
                            return this;
                        },
                        abort: function(statusText) {
                            var finalText = statusText || strAbort;
                            if (transport) {
                                transport.abort(finalText);
                            }
                            done(0, finalText);
                            return this;
                        }
                    };
                deferred.promise(jqXHR).complete = completeDeferred.add;
                jqXHR.success = jqXHR.done;
                jqXHR.error = jqXHR.fail;
                s.url = ((url || s.url || ajaxLocation) + "").replace(rhash, "")
                    .replace(rprotocol, ajaxLocParts[1] + "//");
                s.type = options.method || options.type || s.method || s.type;
                s.dataTypes = jQuery.trim(s.dataType || "*").toLowerCase().match(rnotwhite) || [""];
                if (s.crossDomain == null) {
                    parts = rurl.exec(s.url.toLowerCase());
                    s.crossDomain = !!(parts &&
                        (parts[1] !== ajaxLocParts[1] || parts[2] !== ajaxLocParts[2] ||
                            (parts[3] || (parts[1] === "http:" ? "80" : "443")) !==
                            (ajaxLocParts[3] || (ajaxLocParts[1] === "http:" ? "80" : "443")))
                    );
                }
                if (s.data && s.processData && typeof s.data !== "string") {
                    s.data = jQuery.param(s.data, s.traditional);
                }
                inspectPrefiltersOrTransports(prefilters, s, options, jqXHR);
                if (state === 2) {
                    return jqXHR;
                }
                fireGlobals = jQuery.event && s.global;
                if (fireGlobals && jQuery.active++ === 0) {
                    jQuery.event.trigger("ajaxStart");
                }
                s.type = s.type.toUpperCase();
                s.hasContent = !rnoContent.test(s.type);
                cacheURL = s.url;
                if (!s.hasContent) {
                    if (s.data) {
                        cacheURL = (s.url += (rquery.test(cacheURL) ? "&" : "?") + s.data);
                        delete s.data;
                    }
                    if (s.cache === false) {
                        s.url = rts.test(cacheURL) ?
                            cacheURL.replace(rts, "$1_=" + nonce++) :
                            cacheURL + (rquery.test(cacheURL) ? "&" : "?") + "_=" + nonce++;
                    }
                }
                if (s.ifModified) {
                    if (jQuery.lastModified[cacheURL]) {
                        jqXHR.setRequestHeader("If-Modified-Since", jQuery.lastModified[cacheURL]);
                    }
                    if (jQuery.etag[cacheURL]) {
                        jqXHR.setRequestHeader("If-None-Match", jQuery.etag[cacheURL]);
                    }
                }
                if (s.data && s.hasContent && s.contentType !== false || options.contentType) {
                    jqXHR.setRequestHeader("Content-Type", s.contentType);
                }
                jqXHR.setRequestHeader(
                    "Accept",
                    s.dataTypes[0] && s.accepts[s.dataTypes[0]] ?
                    s.accepts[s.dataTypes[0]] + (s.dataTypes[0] !== "*" ? ", " + allTypes + "; q=0.01" : "") :
                    s.accepts["*"]
                );
                for (i in s.headers) {
                    jqXHR.setRequestHeader(i, s.headers[i]);
                }
                if (s.beforeSend && (s.beforeSend.call(callbackContext, jqXHR, s) === false || state === 2)) {
                    return jqXHR.abort();
                }
                strAbort = "abort";
                for (i in {
                        success: 1,
                        error: 1,
                        complete: 1
                    }) {
                    jqXHR[i](s[i]);
                }
                transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR);
                if (!transport) {
                    done(-1, "No Transport");
                } else {
                    jqXHR.readyState = 1;
                    if (fireGlobals) {
                        globalEventContext.trigger("ajaxSend", [jqXHR, s]);
                    }
                    if (s.async && s.timeout > 0) {
                        timeoutTimer = setTimeout(function() {
                            jqXHR.abort("timeout");
                        }, s.timeout);
                    }
                    try {
                        state = 1;
                        transport.send(requestHeaders, done);
                    } catch (e) {
                        if (state < 2) {
                            done(-1, e);
                        } else {
                            throw e;
                        }
                    }
                }
    
                function done(status, nativeStatusText, responses, headers) {
                    var isSuccess, success, error, response, modified,
                        statusText = nativeStatusText;
                    if (state === 2) {
                        return;
                    }
                    state = 2;
                    if (timeoutTimer) {
                        clearTimeout(timeoutTimer);
                    }
                    transport = undefined;
                    responseHeadersString = headers || "";
                    jqXHR.readyState = status > 0 ? 4 : 0;
                    isSuccess = status >= 200 && status < 300 || status === 304;
                    if (responses) {
                        response = ajaxHandleResponses(s, jqXHR, responses);
                    }
                    response = ajaxConvert(s, response, jqXHR, isSuccess);
                    if (isSuccess) {
                        if (s.ifModified) {
                            modified = jqXHR.getResponseHeader("Last-Modified");
                            if (modified) {
                                jQuery.lastModified[cacheURL] = modified;
                            }
                            modified = jqXHR.getResponseHeader("etag");
                            if (modified) {
                                jQuery.etag[cacheURL] = modified;
                            }
                        }
                        if (status === 204 || s.type === "HEAD") {
                            statusText = "nocontent";
                        } else if (status === 304) {
                            statusText = "notmodified";
                        } else {
                            statusText = response.state;
                            success = response.data;
                            error = response.error;
                            isSuccess = !error;
                        }
                    } else {
                        error = statusText;
                        if (status || !statusText) {
                            statusText = "error";
                            if (status < 0) {
                                status = 0;
                            }
                        }
                    }
                    jqXHR.status = status;
                    jqXHR.statusText = (nativeStatusText || statusText) + "";
                    if (isSuccess) {
                        deferred.resolveWith(callbackContext, [success, statusText, jqXHR]);
                    } else {
                        deferred.rejectWith(callbackContext, [jqXHR, statusText, error]);
                    }
                    jqXHR.statusCode(statusCode);
                    statusCode = undefined;
                    if (fireGlobals) {
                        globalEventContext.trigger(isSuccess ? "ajaxSuccess" : "ajaxError", [jqXHR, s, isSuccess ? success : error]);
                    }
                    completeDeferred.fireWith(callbackContext, [jqXHR, statusText]);
                    if (fireGlobals) {
                        globalEventContext.trigger("ajaxComplete", [jqXHR, s]);
                        if (!(--jQuery.active)) {
                            jQuery.event.trigger("ajaxStop");
                        }
                    }
                }
                return jqXHR;
            },
            getJSON: function(url, data, callback) {
                return jQuery.get(url, data, callback, "json");
            },
            getScript: function(url, callback) {
                return jQuery.get(url, undefined, callback, "script");
            }
        });
        jQuery.each(["get", "post"], function(i, method) {
            jQuery[method] = function(url, data, callback, type) {
                if (jQuery.isFunction(data)) {
                    type = type || callback;
                    callback = data;
                    data = undefined;
                }
                return jQuery.ajax({
                    url: url,
                    type: method,
                    dataType: type,
                    data: data,
                    success: callback
                });
            };
        });
        jQuery._evalUrl = function(url) {
            return jQuery.ajax({
                url: url,
                type: "GET",
                dataType: "script",
                async: false,
                global: false,
                "throws": true
            });
        };
        jQuery.fn.extend({
            wrapAll: function(html) {
                var wrap;
                if (jQuery.isFunction(html)) {
                    return this.each(function(i) {
                        jQuery(this).wrapAll(html.call(this, i));
                    });
                }
                if (this[0]) {
                    wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true);
                    if (this[0].parentNode) {
                        wrap.insertBefore(this[0]);
                    }
                    wrap.map(function() {
                        var elem = this;
                        while (elem.firstElementChild) {
                            elem = elem.firstElementChild;
                        }
                        return elem;
                    }).append(this);
                }
                return this;
            },
            wrapInner: function(html) {
                if (jQuery.isFunction(html)) {
                    return this.each(function(i) {
                        jQuery(this).wrapInner(html.call(this, i));
                    });
                }
                return this.each(function() {
                    var self = jQuery(this),
                        contents = self.contents();
                    if (contents.length) {
                        contents.wrapAll(html);
                    } else {
                        self.append(html);
                    }
                });
            },
            wrap: function(html) {
                var isFunction = jQuery.isFunction(html);
                return this.each(function(i) {
                    jQuery(this).wrapAll(isFunction ? html.call(this, i) : html);
                });
            },
            unwrap: function() {
                return this.parent().each(function() {
                    if (!jQuery.nodeName(this, "body")) {
                        jQuery(this).replaceWith(this.childNodes);
                    }
                }).end();
            }
        });
        jQuery.expr.filters.hidden = function(elem) {
            return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
        };
        jQuery.expr.filters.visible = function(elem) {
            return !jQuery.expr.filters.hidden(elem);
        };
        var r20 = /%20/g,
            rbracket = /\[\]$/,
            rCRLF = /\r?\n/g,
            rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
            rsubmittable = /^(?:input|select|textarea|keygen)/i;
    
        function buildParams(prefix, obj, traditional, add) {
            var name;
            if (jQuery.isArray(obj)) {
                jQuery.each(obj, function(i, v) {
                    if (traditional || rbracket.test(prefix)) {
                        add(prefix, v);
                    } else {
                        buildParams(prefix + "[" + (typeof v === "object" ? i : "") + "]", v, traditional, add);
                    }
                });
            } else if (!traditional && jQuery.type(obj) === "object") {
                for (name in obj) {
                    buildParams(prefix + "[" + name + "]", obj[name], traditional, add);
                }
            } else {
                add(prefix, obj);
            }
        }
        jQuery.param = function(a, traditional) {
            var prefix,
                s = [],
                add = function(key, value) {
                    value = jQuery.isFunction(value) ? value() : (value == null ? "" : value);
                    s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
                };
            if (traditional === undefined) {
                traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
            }
            if (jQuery.isArray(a) || (a.jquery && !jQuery.isPlainObject(a))) {
                jQuery.each(a, function() {
                    add(this.name, this.value);
                });
            } else {
                for (prefix in a) {
                    buildParams(prefix, a[prefix], traditional, add);
                }
            }
            return s.join("&").replace(r20, "+");
        };
        jQuery.fn.extend({
            serialize: function() {
                return jQuery.param(this.serializeArray());
            },
            serializeArray: function() {
                return this.map(function() {
                        var elements = jQuery.prop(this, "elements");
                        return elements ? jQuery.makeArray(elements) : this;
                    })
                    .filter(function() {
                        var type = this.type;
                        return this.name && !jQuery(this).is(":disabled") &&
                            rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) &&
                            (this.checked || !rcheckableType.test(type));
                    })
                    .map(function(i, elem) {
                        var val = jQuery(this).val();
                        return val == null ?
                            null :
                            jQuery.isArray(val) ?
                            jQuery.map(val, function(val) {
                                return {
                                    name: elem.name,
                                    value: val.replace(rCRLF, "\r\n")
                                };
                            }) : {
                                name: elem.name,
                                value: val.replace(rCRLF, "\r\n")
                            };
                    }).get();
            }
        });
        jQuery.ajaxSettings.xhr = function() {
            try {
                return new XMLHttpRequest();
            } catch (e) {}
        };
        var xhrId = 0,
            xhrCallbacks = {},
            xhrSuccessStatus = {
                0: 200,
                1223: 204
            },
            xhrSupported = jQuery.ajaxSettings.xhr();
        if (window.attachEvent) {
            window.attachEvent("onunload", function() {
                for (var key in xhrCallbacks) {
                    xhrCallbacks[key]();
                }
            });
        }
        support.cors = !!xhrSupported && ("withCredentials" in xhrSupported);
        support.ajax = xhrSupported = !!xhrSupported;
        jQuery.ajaxTransport(function(options) {
            var callback;
            if (support.cors || xhrSupported && !options.crossDomain) {
                return {
                    send: function(headers, complete) {
                        var i,
                            xhr = options.xhr(),
                            id = ++xhrId;
                        xhr.open(options.type, options.url, options.async, options.username, options.password);
                        if (options.xhrFields) {
                            for (i in options.xhrFields) {
                                xhr[i] = options.xhrFields[i];
                            }
                        }
                        if (options.mimeType && xhr.overrideMimeType) {
                            xhr.overrideMimeType(options.mimeType);
                        }
                        if (!options.crossDomain && !headers["X-Requested-With"]) {
                            headers["X-Requested-With"] = "XMLHttpRequest";
                        }
                        for (i in headers) {
                            xhr.setRequestHeader(i, headers[i]);
                        }
                        callback = function(type) {
                            return function() {
                                if (callback) {
                                    delete xhrCallbacks[id];
                                    callback = xhr.onload = xhr.onerror = null;
                                    if (type === "abort") {
                                        xhr.abort();
                                    } else if (type === "error") {
                                        complete(
                                            xhr.status,
                                            xhr.statusText
                                        );
                                    } else {
                                        complete(
                                            xhrSuccessStatus[xhr.status] || xhr.status,
                                            xhr.statusText,
                                            typeof xhr.responseText === "string" ? {
                                                text: xhr.responseText
                                            } : undefined,
                                            xhr.getAllResponseHeaders()
                                        );
                                    }
                                }
                            };
                        };
                        xhr.onload = callback();
                        xhr.onerror = callback("error");
                        callback = xhrCallbacks[id] = callback("abort");
                        try {
                            xhr.send(options.hasContent && options.data || null);
                        } catch (e) {
                            if (callback) {
                                throw e;
                            }
                        }
                    },
                    abort: function() {
                        if (callback) {
                            callback();
                        }
                    }
                };
            }
        });
        jQuery.ajaxSetup({
            accepts: {
                script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
            },
            contents: {
                script: /(?:java|ecma)script/
            },
            converters: {
                "text script": function(text) {
                    jQuery.globalEval(text);
                    return text;
                }
            }
        });
        jQuery.ajaxPrefilter("script", function(s) {
            if (s.cache === undefined) {
                s.cache = false;
            }
            if (s.crossDomain) {
                s.type = "GET";
            }
        });
        jQuery.ajaxTransport("script", function(s) {
            if (s.crossDomain) {
                var script, callback;
                return {
                    send: function(_, complete) {
                        script = jQuery("<script>").prop({
                            async: true,
                            charset: s.scriptCharset,
                            src: s.url
                        }).on(
                            "load error",
                            callback = function(evt) {
                                script.remove();
                                callback = null;
                                if (evt) {
                                    complete(evt.type === "error" ? 404 : 200, evt.type);
                                }
                            }
                        );
                        document.head.appendChild(script[0]);
                    },
                    abort: function() {
                        if (callback) {
                            callback();
                        }
                    }
                };
            }
        });
        var oldCallbacks = [],
            rjsonp = /(=)\?(?=&|$)|\?\?/;
        jQuery.ajaxSetup({
            jsonp: "callback",
            jsonpCallback: function() {
                var callback = oldCallbacks.pop() || (jQuery.expando + "_" + (nonce++));
                this[callback] = true;
                return callback;
            }
        });
        jQuery.ajaxPrefilter("json jsonp", function(s, originalSettings, jqXHR) {
            var callbackName, overwritten, responseContainer,
                jsonProp = s.jsonp !== false && (rjsonp.test(s.url) ?
                    "url" :
                    typeof s.data === "string" && !(s.contentType || "").indexOf("application/x-www-form-urlencoded") && rjsonp.test(s.data) && "data"
                );
            if (jsonProp || s.dataTypes[0] === "jsonp") {
                callbackName = s.jsonpCallback = jQuery.isFunction(s.jsonpCallback) ?
                    s.jsonpCallback() :
                    s.jsonpCallback;
                if (jsonProp) {
                    s[jsonProp] = s[jsonProp].replace(rjsonp, "$1" + callbackName);
                } else if (s.jsonp !== false) {
                    s.url += (rquery.test(s.url) ? "&" : "?") + s.jsonp + "=" + callbackName;
                }
                s.converters["script json"] = function() {
                    if (!responseContainer) {
                        jQuery.error(callbackName + " was not called");
                    }
                    return responseContainer[0];
                };
                s.dataTypes[0] = "json";
                overwritten = window[callbackName];
                window[callbackName] = function() {
                    responseContainer = arguments;
                };
                jqXHR.always(function() {
                    window[callbackName] = overwritten;
                    if (s[callbackName]) {
                        s.jsonpCallback = originalSettings.jsonpCallback;
                        oldCallbacks.push(callbackName);
                    }
                    if (responseContainer && jQuery.isFunction(overwritten)) {
                        overwritten(responseContainer[0]);
                    }
                    responseContainer = overwritten = undefined;
                });
                return "script";
            }
        });
        jQuery.parseHTML = function(data, context, keepScripts) {
            if (!data || typeof data !== "string") {
                return null;
            }
            if (typeof context === "boolean") {
                keepScripts = context;
                context = false;
            }
            context = context || document;
            var parsed = rsingleTag.exec(data),
                scripts = !keepScripts && [];
            if (parsed) {
                return [context.createElement(parsed[1])];
            }
            parsed = jQuery.buildFragment([data], context, scripts);
            if (scripts && scripts.length) {
                jQuery(scripts).remove();
            }
            return jQuery.merge([], parsed.childNodes);
        };
        var _load = jQuery.fn.load;
        jQuery.fn.load = function(url, params, callback) {
            if (typeof url !== "string" && _load) {
                return _load.apply(this, arguments);
            }
            var selector, type, response,
                self = this,
                off = url.indexOf(" ");
            if (off >= 0) {
                selector = jQuery.trim(url.slice(off));
                url = url.slice(0, off);
            }
            if (jQuery.isFunction(params)) {
                callback = params;
                params = undefined;
            } else if (params && typeof params === "object") {
                type = "POST";
            }
            if (self.length > 0) {
                jQuery.ajax({
                    url: url,
                    type: type,
                    dataType: "html",
                    data: params
                }).done(function(responseText) {
                    response = arguments;
                    self.html(selector ?
                        jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) :
                        responseText);
                }).complete(callback && function(jqXHR, status) {
                    self.each(callback, response || [jqXHR.responseText, status, jqXHR]);
                });
            }
            return this;
        };
        jQuery.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function(i, type) {
            jQuery.fn[type] = function(fn) {
                return this.on(type, fn);
            };
        });
        jQuery.expr.filters.animated = function(elem) {
            return jQuery.grep(jQuery.timers, function(fn) {
                return elem === fn.elem;
            }).length;
        };
        var docElem = window.document.documentElement;
    
        function getWindow(elem) {
            return jQuery.isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView;
        }
        jQuery.offset = {
            setOffset: function(elem, options, i) {
                var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
                    position = jQuery.css(elem, "position"),
                    curElem = jQuery(elem),
                    props = {};
                if (position === "static") {
                    elem.style.position = "relative";
                }
                curOffset = curElem.offset();
                curCSSTop = jQuery.css(elem, "top");
                curCSSLeft = jQuery.css(elem, "left");
                calculatePosition = (position === "absolute" || position === "fixed") &&
                    (curCSSTop + curCSSLeft).indexOf("auto") > -1;
                if (calculatePosition) {
                    curPosition = curElem.position();
                    curTop = curPosition.top;
                    curLeft = curPosition.left;
                } else {
                    curTop = parseFloat(curCSSTop) || 0;
                    curLeft = parseFloat(curCSSLeft) || 0;
                }
                if (jQuery.isFunction(options)) {
                    options = options.call(elem, i, curOffset);
                }
                if (options.top != null) {
                    props.top = (options.top - curOffset.top) + curTop;
                }
                if (options.left != null) {
                    props.left = (options.left - curOffset.left) + curLeft;
                }
                if ("using" in options) {
                    options.using.call(elem, props);
                } else {
                    curElem.css(props);
                }
            }
        };
        jQuery.fn.extend({
            offset: function(options) {
                if (arguments.length) {
                    return options === undefined ?
                        this :
                        this.each(function(i) {
                            jQuery.offset.setOffset(this, options, i);
                        });
                }
                var docElem, win,
                    elem = this[0],
                    box = {
                        top: 0,
                        left: 0
                    },
                    doc = elem && elem.ownerDocument;
                if (!doc) {
                    return;
                }
                docElem = doc.documentElement;
                if (!jQuery.contains(docElem, elem)) {
                    return box;
                }
                if (typeof elem.getBoundingClientRect !== strundefined) {
                    box = elem.getBoundingClientRect();
                }
                win = getWindow(doc);
                return {
                    top: box.top + win.pageYOffset - docElem.clientTop,
                    left: box.left + win.pageXOffset - docElem.clientLeft
                };
            },
            position: function() {
                if (!this[0]) {
                    return;
                }
                var offsetParent, offset,
                    elem = this[0],
                    parentOffset = {
                        top: 0,
                        left: 0
                    };
                if (jQuery.css(elem, "position") === "fixed") {
                    offset = elem.getBoundingClientRect();
                } else {
                    offsetParent = this.offsetParent();
                    offset = this.offset();
                    if (!jQuery.nodeName(offsetParent[0], "html")) {
                        parentOffset = offsetParent.offset();
                    }
                    parentOffset.top += jQuery.css(offsetParent[0], "borderTopWidth", true);
                    parentOffset.left += jQuery.css(offsetParent[0], "borderLeftWidth", true);
                }
                return {
                    top: offset.top - parentOffset.top - jQuery.css(elem, "marginTop", true),
                    left: offset.left - parentOffset.left - jQuery.css(elem, "marginLeft", true)
                };
            },
            offsetParent: function() {
                return this.map(function() {
                    var offsetParent = this.offsetParent || docElem;
                    while (offsetParent && (!jQuery.nodeName(offsetParent, "html") && jQuery.css(offsetParent, "position") === "static")) {
                        offsetParent = offsetParent.offsetParent;
                    }
                    return offsetParent || docElem;
                });
            }
        });
        jQuery.each({
            scrollLeft: "pageXOffset",
            scrollTop: "pageYOffset"
        }, function(method, prop) {
            var top = "pageYOffset" === prop;
            jQuery.fn[method] = function(val) {
                return access(this, function(elem, method, val) {
                    var win = getWindow(elem);
                    if (val === undefined) {
                        return win ? win[prop] : elem[method];
                    }
                    if (win) {
                        win.scrollTo(!top ? val : window.pageXOffset,
                            top ? val : window.pageYOffset
                        );
                    } else {
                        elem[method] = val;
                    }
                }, method, val, arguments.length, null);
            };
        });
        jQuery.each(["top", "left"], function(i, prop) {
            jQuery.cssHooks[prop] = addGetHookIf(support.pixelPosition,
                function(elem, computed) {
                    if (computed) {
                        computed = curCSS(elem, prop);
                        return rnumnonpx.test(computed) ?
                            jQuery(elem).position()[prop] + "px" :
                            computed;
                    }
                }
            );
        });
        jQuery.each({
            Height: "height",
            Width: "width"
        }, function(name, type) {
            jQuery.each({
                padding: "inner" + name,
                content: type,
                "": "outer" + name
            }, function(defaultExtra, funcName) {
                jQuery.fn[funcName] = function(margin, value) {
                    var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"),
                        extra = defaultExtra || (margin === true || value === true ? "margin" : "border");
                    return access(this, function(elem, type, value) {
                        var doc;
                        if (jQuery.isWindow(elem)) {
                            return elem.document.documentElement["client" + name];
                        }
                        if (elem.nodeType === 9) {
                            doc = elem.documentElement;
                            return Math.max(
                                elem.body["scroll" + name], doc["scroll" + name],
                                elem.body["offset" + name], doc["offset" + name],
                                doc["client" + name]
                            );
                        }
                        return value === undefined ?
                            jQuery.css(elem, type, extra) :
                            jQuery.style(elem, type, value, extra);
                    }, type, chainable ? margin : undefined, chainable, null);
                };
            });
        });
        jQuery.fn.size = function() {
            return this.length;
        };
        jQuery.fn.andSelf = jQuery.fn.addBack;
        if (typeof define === "function" && define.amd) {
            define("jquery", [], function() {
                return jQuery;
            });
        }
        var
            _jQuery = window.jQuery,
            _$ = window.$;
        jQuery.noConflict = function(deep) {
            if (window.$ === jQuery) {
                window.$ = _$;
            }
            if (deep && window.jQuery === jQuery) {
                window.jQuery = _jQuery;
            }
            return jQuery;
        };
        if (typeof noGlobal === strundefined) {
            window.jQuery = window.$ = jQuery;
        }
        return jQuery;
    }));;
    /*! RESOURCE: /scripts/angular_includes_no_min_1.5.3.js */
    /*! RESOURCE: /scripts/angular_1.5.3/angular.js */
    (function(window, document, undefined) {
        'use strict';
    
        function minErr(module, ErrorConstructor) {
            ErrorConstructor = ErrorConstructor || Error;
            return function() {
                var SKIP_INDEXES = 2;
                var templateArgs = arguments,
                    code = templateArgs[0],
                    message = '[' + (module ? module + ':' : '') + code + '] ',
                    template = templateArgs[1],
                    paramPrefix, i;
                message += template.replace(/\{\d+\}/g, function(match) {
                    var index = +match.slice(1, -1),
                        shiftedIndex = index + SKIP_INDEXES;
                    if (shiftedIndex < templateArgs.length) {
                        return toDebugString(templateArgs[shiftedIndex]);
                    }
                    return match;
                });
                message += '\nhttp://errors.angularjs.org/1.5.3/' +
                    (module ? module + '/' : '') + code;
                for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
                    message += paramPrefix + 'p' + (i - SKIP_INDEXES) + '=' +
                        encodeURIComponent(toDebugString(templateArgs[i]));
                }
                return new ErrorConstructor(message);
            };
        }
        var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/;
        var VALIDITY_STATE_PROPERTY = 'validity';
        var hasOwnProperty = Object.prototype.hasOwnProperty;
        var lowercase = function(string) {
            return isString(string) ? string.toLowerCase() : string;
        };
        var uppercase = function(string) {
            return isString(string) ? string.toUpperCase() : string;
        };
        var manualLowercase = function(s) {
            return isString(s) ?
                s.replace(/[A-Z]/g, function(ch) {
                    return String.fromCharCode(ch.charCodeAt(0) | 32);
                }) :
                s;
        };
        var manualUppercase = function(s) {
            return isString(s) ?
                s.replace(/[a-z]/g, function(ch) {
                    return String.fromCharCode(ch.charCodeAt(0) & ~32);
                }) :
                s;
        };
        if ('i' !== 'I'.toLowerCase()) {
            lowercase = manualLowercase;
            uppercase = manualUppercase;
        }
        var
            msie,
            jqLite,
            jQuery,
            slice = [].slice,
            splice = [].splice,
            push = [].push,
            toString = Object.prototype.toString,
            getPrototypeOf = Object.getPrototypeOf,
            ngMinErr = minErr('ng'),
            angular = window.angular || (window.angular = {}),
            angularModule,
            uid = 0;
        msie = document.documentMode;
    
        function isArrayLike(obj) {
            if (obj == null || isWindow(obj)) return false;
            if (isArray(obj) || isString(obj) || (jqLite && obj instanceof jqLite)) return true;
            var length = "length" in Object(obj) && obj.length;
            return isNumber(length) &&
                (length >= 0 && ((length - 1) in obj || obj instanceof Array) || typeof obj.item == 'function');
        }
    
        function forEach(obj, iterator, context) {
            var key, length;
            if (obj) {
                if (isFunction(obj)) {
                    for (key in obj) {
                        if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
                            iterator.call(context, obj[key], key, obj);
                        }
                    }
                } else if (isArray(obj) || isArrayLike(obj)) {
                    var isPrimitive = typeof obj !== 'object';
                    for (key = 0, length = obj.length; key < length; key++) {
                        if (isPrimitive || key in obj) {
                            iterator.call(context, obj[key], key, obj);
                        }
                    }
                } else if (obj.forEach && obj.forEach !== forEach) {
                    obj.forEach(iterator, context, obj);
                } else if (isBlankObject(obj)) {
                    for (key in obj) {
                        iterator.call(context, obj[key], key, obj);
                    }
                } else if (typeof obj.hasOwnProperty === 'function') {
                    for (key in obj) {
                        if (obj.hasOwnProperty(key)) {
                            iterator.call(context, obj[key], key, obj);
                        }
                    }
                } else {
                    for (key in obj) {
                        if (hasOwnProperty.call(obj, key)) {
                            iterator.call(context, obj[key], key, obj);
                        }
                    }
                }
            }
            return obj;
        }
    
        function forEachSorted(obj, iterator, context) {
            var keys = Object.keys(obj).sort();
            for (var i = 0; i < keys.length; i++) {
                iterator.call(context, obj[keys[i]], keys[i]);
            }
            return keys;
        }
    
        function reverseParams(iteratorFn) {
            return function(value, key) {
                iteratorFn(key, value);
            };
        }
    
        function nextUid() {
            return ++uid;
        }
    
        function setHashKey(obj, h) {
            if (h) {
                obj.$$hashKey = h;
            } else {
                delete obj.$$hashKey;
            }
        }
    
        function baseExtend(dst, objs, deep) {
            var h = dst.$$hashKey;
            for (var i = 0, ii = objs.length; i < ii; ++i) {
                var obj = objs[i];
                if (!isObject(obj) && !isFunction(obj)) continue;
                var keys = Object.keys(obj);
                for (var j = 0, jj = keys.length; j < jj; j++) {
                    var key = keys[j];
                    var src = obj[key];
                    if (deep && isObject(src)) {
                        if (isDate(src)) {
                            dst[key] = new Date(src.valueOf());
                        } else if (isRegExp(src)) {
                            dst[key] = new RegExp(src);
                        } else if (src.nodeName) {
                            dst[key] = src.cloneNode(true);
                        } else if (isElement(src)) {
                            dst[key] = src.clone();
                        } else {
                            if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
                            baseExtend(dst[key], [src], true);
                        }
                    } else {
                        dst[key] = src;
                    }
                }
            }
            setHashKey(dst, h);
            return dst;
        }
    
        function extend(dst) {
            return baseExtend(dst, slice.call(arguments, 1), false);
        }
    
        function merge(dst) {
            return baseExtend(dst, slice.call(arguments, 1), true);
        }
    
        function toInt(str) {
            return parseInt(str, 10);
        }
    
        function inherit(parent, extra) {
            return extend(Object.create(parent), extra);
        }
    
        function noop() {}
        noop.$inject = [];
    
        function identity($) {
            return $;
        }
        identity.$inject = [];
    
        function valueFn(value) {
            return function valueRef() {
                return value;
            };
        }
    
        function hasCustomToString(obj) {
            return isFunction(obj.toString) && obj.toString !== toString;
        }
    
        function isUndefined(value) {
            return typeof value === 'undefined';
        }
    
        function isDefined(value) {
            return typeof value !== 'undefined';
        }
    
        function isObject(value) {
            return value !== null && typeof value === 'object';
        }
    
        function isBlankObject(value) {
            return value !== null && typeof value === 'object' && !getPrototypeOf(value);
        }
    
        function isString(value) {
            return typeof value === 'string';
        }
    
        function isNumber(value) {
            return typeof value === 'number';
        }
    
        function isDate(value) {
            return toString.call(value) === '[object Date]';
        }
        var isArray = Array.isArray;
    
        function isFunction(value) {
            return typeof value === 'function';
        }
    
        function isRegExp(value) {
            return toString.call(value) === '[object RegExp]';
        }
    
        function isWindow(obj) {
            return obj && obj.window === obj;
        }
    
        function isScope(obj) {
            return obj && obj.$evalAsync && obj.$watch;
        }
    
        function isFile(obj) {
            return toString.call(obj) === '[object File]';
        }
    
        function isFormData(obj) {
            return toString.call(obj) === '[object FormData]';
        }
    
        function isBlob(obj) {
            return toString.call(obj) === '[object Blob]';
        }
    
        function isBoolean(value) {
            return typeof value === 'boolean';
        }
    
        function isPromiseLike(obj) {
            return obj && isFunction(obj.then);
        }
        var TYPED_ARRAY_REGEXP = /^\[object (?:Uint8|Uint8Clamped|Uint16|Uint32|Int8|Int16|Int32|Float32|Float64)Array\]$/;
    
        function isTypedArray(value) {
            return value && isNumber(value.length) && TYPED_ARRAY_REGEXP.test(toString.call(value));
        }
    
        function isArrayBuffer(obj) {
            return toString.call(obj) === '[object ArrayBuffer]';
        }
        var trim = function(value) {
            return isString(value) ? value.trim() : value;
        };
        var escapeForRegexp = function(s) {
            return s.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1').
            replace(/\x08/g, '\\x08');
        };
    
        function isElement(node) {
            return !!(node &&
                (node.nodeName ||
                    (node.prop && node.attr && node.find)));
        }
    
        function makeMap(str) {
            var obj = {},
                items = str.split(','),
                i;
            for (i = 0; i < items.length; i++) {
                obj[items[i]] = true;
            }
            return obj;
        }
    
        function nodeName_(element) {
            return lowercase(element.nodeName || (element[0] && element[0].nodeName));
        }
    
        function includes(array, obj) {
            return Array.prototype.indexOf.call(array, obj) != -1;
        }
    
        function arrayRemove(array, value) {
            var index = array.indexOf(value);
            if (index >= 0) {
                array.splice(index, 1);
            }
            return index;
        }
    
        function copy(source, destination) {
            var stackSource = [];
            var stackDest = [];
            if (destination) {
                if (isTypedArray(destination) || isArrayBuffer(destination)) {
                    throw ngMinErr('cpta', "Can't copy! TypedArray destination cannot be mutated.");
                }
                if (source === destination) {
                    throw ngMinErr('cpi', "Can't copy! Source and destination are identical.");
                }
                if (isArray(destination)) {
                    destination.length = 0;
                } else {
                    forEach(destination, function(value, key) {
                        if (key !== '$$hashKey') {
                            delete destination[key];
                        }
                    });
                }
                stackSource.push(source);
                stackDest.push(destination);
                return copyRecurse(source, destination);
            }
            return copyElement(source);
    
            function copyRecurse(source, destination) {
                var h = destination.$$hashKey;
                var key;
                if (isArray(source)) {
                    for (var i = 0, ii = source.length; i < ii; i++) {
                        destination.push(copyElement(source[i]));
                    }
                } else if (isBlankObject(source)) {
                    for (key in source) {
                        destination[key] = copyElement(source[key]);
                    }
                } else if (source && typeof source.hasOwnProperty === 'function') {
                    for (key in source) {
                        if (source.hasOwnProperty(key)) {
                            destination[key] = copyElement(source[key]);
                        }
                    }
                } else {
                    for (key in source) {
                        if (hasOwnProperty.call(source, key)) {
                            destination[key] = copyElement(source[key]);
                        }
                    }
                }
                setHashKey(destination, h);
                return destination;
            }
    
            function copyElement(source) {
                if (!isObject(source)) {
                    return source;
                }
                var index = stackSource.indexOf(source);
                if (index !== -1) {
                    return stackDest[index];
                }
                if (isWindow(source) || isScope(source)) {
                    throw ngMinErr('cpws',
                        "Can't copy! Making copies of Window or Scope instances is not supported.");
                }
                var needsRecurse = false;
                var destination = copyType(source);
                if (destination === undefined) {
                    destination = isArray(source) ? [] : Object.create(getPrototypeOf(source));
                    needsRecurse = true;
                }
                stackSource.push(source);
                stackDest.push(destination);
                return needsRecurse ?
                    copyRecurse(source, destination) :
                    destination;
            }
    
            function copyType(source) {
                switch (toString.call(source)) {
                    case '[object Int8Array]':
                    case '[object Int16Array]':
                    case '[object Int32Array]':
                    case '[object Float32Array]':
                    case '[object Float64Array]':
                    case '[object Uint8Array]':
                    case '[object Uint8ClampedArray]':
                    case '[object Uint16Array]':
                    case '[object Uint32Array]':
                        return new source.constructor(copyElement(source.buffer));
                    case '[object ArrayBuffer]':
                        if (!source.slice) {
                            var copied = new ArrayBuffer(source.byteLength);
                            new Uint8Array(copied).set(new Uint8Array(source));
                            return copied;
                        }
                        return source.slice(0);
                    case '[object Boolean]':
                    case '[object Number]':
                    case '[object String]':
                    case '[object Date]':
                        return new source.constructor(source.valueOf());
                    case '[object RegExp]':
                        var re = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]);
                        re.lastIndex = source.lastIndex;
                        return re;
                    case '[object Blob]':
                        return new source.constructor([source], {
                            type: source.type
                        });
                }
                if (isFunction(source.cloneNode)) {
                    return source.cloneNode(true);
                }
            }
        }
    
        function shallowCopy(src, dst) {
            if (isArray(src)) {
                dst = dst || [];
                for (var i = 0, ii = src.length; i < ii; i++) {
                    dst[i] = src[i];
                }
            } else if (isObject(src)) {
                dst = dst || {};
                for (var key in src) {
                    if (!(key.charAt(0) === '$' && key.charAt(1) === '$')) {
                        dst[key] = src[key];
                    }
                }
            }
            return dst || src;
        }
    
        function equals(o1, o2) {
            if (o1 === o2) return true;
            if (o1 === null || o2 === null) return false;
            if (o1 !== o1 && o2 !== o2) return true;
            var t1 = typeof o1,
                t2 = typeof o2,
                length, key, keySet;
            if (t1 == t2 && t1 == 'object') {
                if (isArray(o1)) {
                    if (!isArray(o2)) return false;
                    if ((length = o1.length) == o2.length) {
                        for (key = 0; key < length; key++) {
                            if (!equals(o1[key], o2[key])) return false;
                        }
                        return true;
                    }
                } else if (isDate(o1)) {
                    if (!isDate(o2)) return false;
                    return equals(o1.getTime(), o2.getTime());
                } else if (isRegExp(o1)) {
                    if (!isRegExp(o2)) return false;
                    return o1.toString() == o2.toString();
                } else {
                    if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) ||
                        isArray(o2) || isDate(o2) || isRegExp(o2)) return false;
                    keySet = createMap();
                    for (key in o1) {
                        if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
                        if (!equals(o1[key], o2[key])) return false;
                        keySet[key] = true;
                    }
                    for (key in o2) {
                        if (!(key in keySet) &&
                            key.charAt(0) !== '$' &&
                            isDefined(o2[key]) &&
                            !isFunction(o2[key])) return false;
                    }
                    return true;
                }
            }
            return false;
        }
        var csp = function() {
            if (!isDefined(csp.rules)) {
                var ngCspElement = (document.querySelector('[ng-csp]') ||
                    document.querySelector('[data-ng-csp]'));
                if (ngCspElement) {
                    var ngCspAttribute = ngCspElement.getAttribute('ng-csp') ||
                        ngCspElement.getAttribute('data-ng-csp');
                    csp.rules = {
                        noUnsafeEval: !ngCspAttribute || (ngCspAttribute.indexOf('no-unsafe-eval') !== -1),
                        noInlineStyle: !ngCspAttribute || (ngCspAttribute.indexOf('no-inline-style') !== -1)
                    };
                } else {
                    csp.rules = {
                        noUnsafeEval: noUnsafeEval(),
                        noInlineStyle: false
                    };
                }
            }
            return csp.rules;
    
            function noUnsafeEval() {
                try {
                    new Function('');
                    return false;
                } catch (e) {
                    return true;
                }
            }
        };
        var jq = function() {
            if (isDefined(jq.name_)) return jq.name_;
            var el;
            var i, ii = ngAttrPrefixes.length,
                prefix, name;
            for (i = 0; i < ii; ++i) {
                prefix = ngAttrPrefixes[i];
                if (el = document.querySelector('[' + prefix.replace(':', '\\:') + 'jq]')) {
                    name = el.getAttribute(prefix + 'jq');
                    break;
                }
            }
            return (jq.name_ = name);
        };
    
        function concat(array1, array2, index) {
            return array1.concat(slice.call(array2, index));
        }
    
        function sliceArgs(args, startIndex) {
            return slice.call(args, startIndex || 0);
        }
    
        function bind(self, fn) {
            var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];
            if (isFunction(fn) && !(fn instanceof RegExp)) {
                return curryArgs.length ?
                    function() {
                        return arguments.length ?
                            fn.apply(self, concat(curryArgs, arguments, 0)) :
                            fn.apply(self, curryArgs);
                    } :
                    function() {
                        return arguments.length ?
                            fn.apply(self, arguments) :
                            fn.call(self);
                    };
            } else {
                return fn;
            }
        }
    
        function toJsonReplacer(key, value) {
            var val = value;
            if (typeof key === 'string' && key.charAt(0) === '$' && key.charAt(1) === '$') {
                val = undefined;
            } else if (isWindow(value)) {
                val = '$WINDOW';
            } else if (value && document === value) {
                val = '$DOCUMENT';
            } else if (isScope(value)) {
                val = '$SCOPE';
            }
            return val;
        }
    
        function toJson(obj, pretty) {
            if (isUndefined(obj)) return undefined;
            if (!isNumber(pretty)) {
                pretty = pretty ? 2 : null;
            }
            return JSON.stringify(obj, toJsonReplacer, pretty);
        }
    
        function fromJson(json) {
            return isString(json) ?
                JSON.parse(json) :
                json;
        }
        var ALL_COLONS = /:/g;
    
        function timezoneToOffset(timezone, fallback) {
            timezone = timezone.replace(ALL_COLONS, '');
            var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;
            return isNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;
        }
    
        function addDateMinutes(date, minutes) {
            date = new Date(date.getTime());
            date.setMinutes(date.getMinutes() + minutes);
            return date;
        }
    
        function convertTimezoneToLocal(date, timezone, reverse) {
            reverse = reverse ? -1 : 1;
            var dateTimezoneOffset = date.getTimezoneOffset();
            var timezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
            return addDateMinutes(date, reverse * (timezoneOffset - dateTimezoneOffset));
        }
    
        function startingTag(element) {
            element = jqLite(element).clone();
            try {
                element.empty();
            } catch (e) {}
            var elemHtml = jqLite('<div>').append(element).html();
            try {
                return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) :
                    elemHtml.
                match(/^(<[^>]+>)/)[1].
                replace(/^<([\w\-]+)/, function(match, nodeName) {
                    return '<' + lowercase(nodeName);
                });
            } catch (e) {
                return lowercase(elemHtml);
            }
        }
    
        function tryDecodeURIComponent(value) {
            try {
                return decodeURIComponent(value);
            } catch (e) {}
        }
    
        function parseKeyValue(keyValue) {
            var obj = {};
            forEach((keyValue || "").split('&'), function(keyValue) {
                var splitPoint, key, val;
                if (keyValue) {
                    key = keyValue = keyValue.replace(/\+/g, '%20');
                    splitPoint = keyValue.indexOf('=');
                    if (splitPoint !== -1) {
                        key = keyValue.substring(0, splitPoint);
                        val = keyValue.substring(splitPoint + 1);
                    }
                    key = tryDecodeURIComponent(key);
                    if (isDefined(key)) {
                        val = isDefined(val) ? tryDecodeURIComponent(val) : true;
                        if (!hasOwnProperty.call(obj, key)) {
                            obj[key] = val;
                        } else if (isArray(obj[key])) {
                            obj[key].push(val);
                        } else {
                            obj[key] = [obj[key], val];
                        }
                    }
                }
            });
            return obj;
        }
    
        function toKeyValue(obj) {
            var parts = [];
            forEach(obj, function(value, key) {
                if (isArray(value)) {
                    forEach(value, function(arrayValue) {
                        parts.push(encodeUriQuery(key, true) +
                            (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true)));
                    });
                } else {
                    parts.push(encodeUriQuery(key, true) +
                        (value === true ? '' : '=' + encodeUriQuery(value, true)));
                }
            });
            return parts.length ? parts.join('&') : '';
        }
    
        function encodeUriSegment(val) {
            return encodeUriQuery(val, true).
            replace(/%26/gi, '&').
            replace(/%3D/gi, '=').
            replace(/%2B/gi, '+');
        }
    
        function encodeUriQuery(val, pctEncodeSpaces) {
            return encodeURIComponent(val).
            replace(/%40/gi, '@').
            replace(/%3A/gi, ':').
            replace(/%24/g, '$').
            replace(/%2C/gi, ',').
            replace(/%3B/gi, ';').
            replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
        }
        var ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-'];
    
        function getNgAttribute(element, ngAttr) {
            var attr, i, ii = ngAttrPrefixes.length;
            for (i = 0; i < ii; ++i) {
                attr = ngAttrPrefixes[i] + ngAttr;
                if (isString(attr = element.getAttribute(attr))) {
                    return attr;
                }
            }
            return null;
        }
    
        function angularInit(element, bootstrap) {
            var appElement,
                module,
                config = {};
            forEach(ngAttrPrefixes, function(prefix) {
                var name = prefix + 'app';
                if (!appElement && element.hasAttribute && element.hasAttribute(name)) {
                    appElement = element;
                    module = element.getAttribute(name);
                }
            });
            forEach(ngAttrPrefixes, function(prefix) {
                var name = prefix + 'app';
                var candidate;
                if (!appElement && (candidate = element.querySelector('[' + name.replace(':', '\\:') + ']'))) {
                    appElement = candidate;
                    module = candidate.getAttribute(name);
                }
            });
            if (appElement) {
                config.strictDi = getNgAttribute(appElement, "strict-di") !== null;
                bootstrap(appElement, module ? [module] : [], config);
            }
        }
    
        function bootstrap(element, modules, config) {
            if (!isObject(config)) config = {};
            var defaultConfig = {
                strictDi: false
            };
            config = extend(defaultConfig, config);
            var doBootstrap = function() {
                element = jqLite(element);
                if (element.injector()) {
                    var tag = (element[0] === document) ? 'document' : startingTag(element);
                    throw ngMinErr(
                        'btstrpd',
                        "App Already Bootstrapped with this Element '{0}'",
                        tag.replace(/</, '&lt;').replace(/>/, '&gt;'));
                }
                modules = modules || [];
                modules.unshift(['$provide', function($provide) {
                    $provide.value('$rootElement', element);
                }]);
                if (config.debugInfoEnabled) {
                    modules.push(['$compileProvider', function($compileProvider) {
                        $compileProvider.debugInfoEnabled(true);
                    }]);
                }
                modules.unshift('ng');
                var injector = createInjector(modules, config.strictDi);
                injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
                    function bootstrapApply(scope, element, compile, injector) {
                        scope.$apply(function() {
                            element.data('$injector', injector);
                            compile(element)(scope);
                        });
                    }
                ]);
                return injector;
            };
            var NG_ENABLE_DEBUG_INFO = /^NG_ENABLE_DEBUG_INFO!/;
            var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
            if (window && NG_ENABLE_DEBUG_INFO.test(window.name)) {
                config.debugInfoEnabled = true;
                window.name = window.name.replace(NG_ENABLE_DEBUG_INFO, '');
            }
            if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
                return doBootstrap();
            }
            window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
            angular.resumeBootstrap = function(extraModules) {
                forEach(extraModules, function(module) {
                    modules.push(module);
                });
                return doBootstrap();
            };
            if (isFunction(angular.resumeDeferredBootstrap)) {
                angular.resumeDeferredBootstrap();
            }
        }
    
        function reloadWithDebugInfo() {
            window.name = 'NG_ENABLE_DEBUG_INFO!' + window.name;
            window.location.reload();
        }
    
        function getTestability(rootElement) {
            var injector = angular.element(rootElement).injector();
            if (!injector) {
                throw ngMinErr('test',
                    'no injector found for element argument to getTestability');
            }
            return injector.get('$$testability');
        }
        var SNAKE_CASE_REGEXP = /[A-Z]/g;
    
        function snake_case(name, separator) {
            separator = separator || '_';
            return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {
                return (pos ? separator : '') + letter.toLowerCase();
            });
        }
        var bindJQueryFired = false;
    
        function bindJQuery() {
            var originalCleanData;
            if (bindJQueryFired) {
                return;
            }
            var jqName = jq();
            jQuery = isUndefined(jqName) ? window.jQuery :
                !jqName ? undefined :
                window[jqName];
            if (jQuery && jQuery.fn.on) {
                jqLite = jQuery;
                extend(jQuery.fn, {
                    scope: JQLitePrototype.scope,
                    isolateScope: JQLitePrototype.isolateScope,
                    controller: JQLitePrototype.controller,
                    injector: JQLitePrototype.injector,
                    inheritedData: JQLitePrototype.inheritedData
                });
                originalCleanData = jQuery.cleanData;
                jQuery.cleanData = function(elems) {
                    var events;
                    for (var i = 0, elem;
                        (elem = elems[i]) != null; i++) {
                        events = jQuery._data(elem, "events");
                        if (events && events.$destroy) {
                            jQuery(elem).triggerHandler('$destroy');
                        }
                    }
                    originalCleanData(elems);
                };
            } else {
                jqLite = JQLite;
            }
            angular.element = jqLite;
            bindJQueryFired = true;
        }
    
        function assertArg(arg, name, reason) {
            if (!arg) {
                throw ngMinErr('areq', "Argument '{0}' is {1}", (name || '?'), (reason || "required"));
            }
            return arg;
        }
    
        function assertArgFn(arg, name, acceptArrayAnnotation) {
            if (acceptArrayAnnotation && isArray(arg)) {
                arg = arg[arg.length - 1];
            }
            assertArg(isFunction(arg), name, 'not a function, got ' +
                (arg && typeof arg === 'object' ? arg.constructor.name || 'Object' : typeof arg));
            return arg;
        }
    
        function assertNotHasOwnProperty(name, context) {
            if (name === 'hasOwnProperty') {
                throw ngMinErr('badname', "hasOwnProperty is not a valid {0} name", context);
            }
        }
    
        function getter(obj, path, bindFnToScope) {
            if (!path) return obj;
            var keys = path.split('.');
            var key;
            var lastInstance = obj;
            var len = keys.length;
            for (var i = 0; i < len; i++) {
                key = keys[i];
                if (obj) {
                    obj = (lastInstance = obj)[key];
                }
            }
            if (!bindFnToScope && isFunction(obj)) {
                return bind(lastInstance, obj);
            }
            return obj;
        }
    
        function getBlockNodes(nodes) {
            var node = nodes[0];
            var endNode = nodes[nodes.length - 1];
            var blockNodes;
            for (var i = 1; node !== endNode && (node = node.nextSibling); i++) {
                if (blockNodes || nodes[i] !== node) {
                    if (!blockNodes) {
                        blockNodes = jqLite(slice.call(nodes, 0, i));
                    }
                    blockNodes.push(node);
                }
            }
            return blockNodes || nodes;
        }
    
        function createMap() {
            return Object.create(null);
        }
        var NODE_TYPE_ELEMENT = 1;
        var NODE_TYPE_ATTRIBUTE = 2;
        var NODE_TYPE_TEXT = 3;
        var NODE_TYPE_COMMENT = 8;
        var NODE_TYPE_DOCUMENT = 9;
        var NODE_TYPE_DOCUMENT_FRAGMENT = 11;
    
        function setupModuleLoader(window) {
            var $injectorMinErr = minErr('$injector');
            var ngMinErr = minErr('ng');
    
            function ensure(obj, name, factory) {
                return obj[name] || (obj[name] = factory());
            }
            var angular = ensure(window, 'angular', Object);
            angular.$$minErr = angular.$$minErr || minErr;
            return ensure(angular, 'module', function() {
                var modules = {};
                return function module(name, requires, configFn) {
                    var assertNotHasOwnProperty = function(name, context) {
                        if (name === 'hasOwnProperty') {
                            throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
                        }
                    };
                    assertNotHasOwnProperty(name, 'module');
                    if (requires && modules.hasOwnProperty(name)) {
                        modules[name] = null;
                    }
                    return ensure(modules, name, function() {
                        if (!requires) {
                            throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " +
                                "the module name or forgot to load it. If registering a module ensure that you " +
                                "specify the dependencies as the second argument.", name);
                        }
                        var invokeQueue = [];
                        var configBlocks = [];
                        var runBlocks = [];
                        var config = invokeLater('$injector', 'invoke', 'push', configBlocks);
                        var moduleInstance = {
                            _invokeQueue: invokeQueue,
                            _configBlocks: configBlocks,
                            _runBlocks: runBlocks,
                            requires: requires,
                            name: name,
                            provider: invokeLaterAndSetModuleName('$provide', 'provider'),
                            factory: invokeLaterAndSetModuleName('$provide', 'factory'),
                            service: invokeLaterAndSetModuleName('$provide', 'service'),
                            value: invokeLater('$provide', 'value'),
                            constant: invokeLater('$provide', 'constant', 'unshift'),
                            decorator: invokeLaterAndSetModuleName('$provide', 'decorator'),
                            animation: invokeLaterAndSetModuleName('$animateProvider', 'register'),
                            filter: invokeLaterAndSetModuleName('$filterProvider', 'register'),
                            controller: invokeLaterAndSetModuleName('$controllerProvider', 'register'),
                            directive: invokeLaterAndSetModuleName('$compileProvider', 'directive'),
                            component: invokeLaterAndSetModuleName('$compileProvider', 'component'),
                            config: config,
                            run: function(block) {
                                runBlocks.push(block);
                                return this;
                            }
                        };
                        if (configFn) {
                            config(configFn);
                        }
                        return moduleInstance;
    
                        function invokeLater(provider, method, insertMethod, queue) {
                            if (!queue) queue = invokeQueue;
                            return function() {
                                queue[insertMethod || 'push']([provider, method, arguments]);
                                return moduleInstance;
                            };
                        }
    
                        function invokeLaterAndSetModuleName(provider, method) {
                            return function(recipeName, factoryFunction) {
                                if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;
                                invokeQueue.push([provider, method, arguments]);
                                return moduleInstance;
                            };
                        }
                    });
                };
            });
        }
    
        function serializeObject(obj) {
            var seen = [];
            return JSON.stringify(obj, function(key, val) {
                val = toJsonReplacer(key, val);
                if (isObject(val)) {
                    if (seen.indexOf(val) >= 0) return '...';
                    seen.push(val);
                }
                return val;
            });
        }
    
        function toDebugString(obj) {
            if (typeof obj === 'function') {
                return obj.toString().replace(/ \{[\s\S]*$/, '');
            } else if (isUndefined(obj)) {
                return 'undefined';
            } else if (typeof obj !== 'string') {
                return serializeObject(obj);
            }
            return obj;
        }
        var version = {
            full: '1.5.3',
            major: 1,
            minor: 5,
            dot: 3,
            codeName: 'diplohaplontic-meiosis'
        };
    
        function publishExternalAPI(angular) {
            extend(angular, {
                'bootstrap': bootstrap,
                'copy': copy,
                'extend': extend,
                'merge': merge,
                'equals': equals,
                'element': jqLite,
                'forEach': forEach,
                'injector': createInjector,
                'noop': noop,
                'bind': bind,
                'toJson': toJson,
                'fromJson': fromJson,
                'identity': identity,
                'isUndefined': isUndefined,
                'isDefined': isDefined,
                'isString': isString,
                'isFunction': isFunction,
                'isObject': isObject,
                'isNumber': isNumber,
                'isElement': isElement,
                'isArray': isArray,
                'version': version,
                'isDate': isDate,
                'lowercase': lowercase,
                'uppercase': uppercase,
                'callbacks': {
                    counter: 0
                },
                'getTestability': getTestability,
                '$$minErr': minErr,
                '$$csp': csp,
                'reloadWithDebugInfo': reloadWithDebugInfo
            });
            angularModule = setupModuleLoader(window);
            angularModule('ng', ['ngLocale'], ['$provide',
                function ngModule($provide) {
                    $provide.provider({
                        $$sanitizeUri: $$SanitizeUriProvider
                    });
                    $provide.provider('$compile', $CompileProvider).
                    directive({
                        a: htmlAnchorDirective,
                        input: inputDirective,
                        textarea: inputDirective,
                        form: formDirective,
                        script: scriptDirective,
                        select: selectDirective,
                        style: styleDirective,
                        option: optionDirective,
                        ngBind: ngBindDirective,
                        ngBindHtml: ngBindHtmlDirective,
                        ngBindTemplate: ngBindTemplateDirective,
                        ngClass: ngClassDirective,
                        ngClassEven: ngClassEvenDirective,
                        ngClassOdd: ngClassOddDirective,
                        ngCloak: ngCloakDirective,
                        ngController: ngControllerDirective,
                        ngForm: ngFormDirective,
                        ngHide: ngHideDirective,
                        ngIf: ngIfDirective,
                        ngInclude: ngIncludeDirective,
                        ngInit: ngInitDirective,
                        ngNonBindable: ngNonBindableDirective,
                        ngPluralize: ngPluralizeDirective,
                        ngRepeat: ngRepeatDirective,
                        ngShow: ngShowDirective,
                        ngStyle: ngStyleDirective,
                        ngSwitch: ngSwitchDirective,
                        ngSwitchWhen: ngSwitchWhenDirective,
                        ngSwitchDefault: ngSwitchDefaultDirective,
                        ngOptions: ngOptionsDirective,
                        ngTransclude: ngTranscludeDirective,
                        ngModel: ngModelDirective,
                        ngList: ngListDirective,
                        ngChange: ngChangeDirective,
                        pattern: patternDirective,
                        ngPattern: patternDirective,
                        required: requiredDirective,
                        ngRequired: requiredDirective,
                        minlength: minlengthDirective,
                        ngMinlength: minlengthDirective,
                        maxlength: maxlengthDirective,
                        ngMaxlength: maxlengthDirective,
                        ngValue: ngValueDirective,
                        ngModelOptions: ngModelOptionsDirective
                    }).
                    directive({
                        ngInclude: ngIncludeFillContentDirective
                    }).
                    directive(ngAttributeAliasDirectives).
                    directive(ngEventDirectives);
                    $provide.provider({
                        $anchorScroll: $AnchorScrollProvider,
                        $animate: $AnimateProvider,
                        $animateCss: $CoreAnimateCssProvider,
                        $$animateJs: $$CoreAnimateJsProvider,
                        $$animateQueue: $$CoreAnimateQueueProvider,
                        $$AnimateRunner: $$AnimateRunnerFactoryProvider,
                        $$animateAsyncRun: $$AnimateAsyncRunFactoryProvider,
                        $browser: $BrowserProvider,
                        $cacheFactory: $CacheFactoryProvider,
                        $controller: $ControllerProvider,
                        $document: $DocumentProvider,
                        $exceptionHandler: $ExceptionHandlerProvider,
                        $filter: $FilterProvider,
                        $$forceReflow: $$ForceReflowProvider,
                        $interpolate: $InterpolateProvider,
                        $interval: $IntervalProvider,
                        $http: $HttpProvider,
                        $httpParamSerializer: $HttpParamSerializerProvider,
                        $httpParamSerializerJQLike: $HttpParamSerializerJQLikeProvider,
                        $httpBackend: $HttpBackendProvider,
                        $xhrFactory: $xhrFactoryProvider,
                        $location: $LocationProvider,
                        $log: $LogProvider,
                        $parse: $ParseProvider,
                        $rootScope: $RootScopeProvider,
                        $q: $QProvider,
                        $$q: $$QProvider,
                        $sce: $SceProvider,
                        $sceDelegate: $SceDelegateProvider,
                        $sniffer: $SnifferProvider,
                        $templateCache: $TemplateCacheProvider,
                        $templateRequest: $TemplateRequestProvider,
                        $$testability: $$TestabilityProvider,
                        $timeout: $TimeoutProvider,
                        $window: $WindowProvider,
                        $$rAF: $$RAFProvider,
                        $$jqLite: $$jqLiteProvider,
                        $$HashMap: $$HashMapProvider,
                        $$cookieReader: $$CookieReaderProvider
                    });
                }
            ]);
        }
        JQLite.expando = 'ng339';
        var jqCache = JQLite.cache = {},
            jqId = 1,
            addEventListenerFn = function(element, type, fn) {
                element.addEventListener(type, fn, false);
            },
            removeEventListenerFn = function(element, type, fn) {
                element.removeEventListener(type, fn, false);
            };
        JQLite._data = function(node) {
            return this.cache[node[this.expando]] || {};
        };
    
        function jqNextId() {
            return ++jqId;
        }
        var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
        var MOZ_HACK_REGEXP = /^moz([A-Z])/;
        var MOUSE_EVENT_MAP = {
            mouseleave: "mouseout",
            mouseenter: "mouseover"
        };
        var jqLiteMinErr = minErr('jqLite');
    
        function camelCase(name) {
            return name.
            replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
                return offset ? letter.toUpperCase() : letter;
            }).
            replace(MOZ_HACK_REGEXP, 'Moz$1');
        }
        var SINGLE_TAG_REGEXP = /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/;
        var HTML_REGEXP = /<|&#?\w+;/;
        var TAG_NAME_REGEXP = /<([\w:-]+)/;
        var XHTML_TAG_REGEXP = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi;
        var wrapMap = {
            'option': [1, '<select multiple="multiple">', '</select>'],
            'thead': [1, '<table>', '</table>'],
            'col': [2, '<table><colgroup>', '</colgroup></table>'],
            'tr': [2, '<table><tbody>', '</tbody></table>'],
            'td': [3, '<table><tbody><tr>', '</tr></tbody></table>'],
            '_default': [0, "", ""]
        };
        wrapMap.optgroup = wrapMap.option;
        wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
        wrapMap.th = wrapMap.td;
    
        function jqLiteIsTextNode(html) {
            return !HTML_REGEXP.test(html);
        }
    
        function jqLiteAcceptsData(node) {
            var nodeType = node.nodeType;
            return nodeType === NODE_TYPE_ELEMENT || !nodeType || nodeType === NODE_TYPE_DOCUMENT;
        }
    
        function jqLiteHasData(node) {
            for (var key in jqCache[node.ng339]) {
                return true;
            }
            return false;
        }
    
        function jqLiteCleanData(nodes) {
            for (var i = 0, ii = nodes.length; i < ii; i++) {
                jqLiteRemoveData(nodes[i]);
            }
        }
    
        function jqLiteBuildFragment(html, context) {
            var tmp, tag, wrap,
                fragment = context.createDocumentFragment(),
                nodes = [],
                i;
            if (jqLiteIsTextNode(html)) {
                nodes.push(context.createTextNode(html));
            } else {
                tmp = tmp || fragment.appendChild(context.createElement("div"));
                tag = (TAG_NAME_REGEXP.exec(html) || ["", ""])[1].toLowerCase();
                wrap = wrapMap[tag] || wrapMap._default;
                tmp.innerHTML = wrap[1] + html.replace(XHTML_TAG_REGEXP, "<$1></$2>") + wrap[2];
                i = wrap[0];
                while (i--) {
                    tmp = tmp.lastChild;
                }
                nodes = concat(nodes, tmp.childNodes);
                tmp = fragment.firstChild;
                tmp.textContent = "";
            }
            fragment.textContent = "";
            fragment.innerHTML = "";
            forEach(nodes, function(node) {
                fragment.appendChild(node);
            });
            return fragment;
        }
    
        function jqLiteParseHTML(html, context) {
            context = context || document;
            var parsed;
            if ((parsed = SINGLE_TAG_REGEXP.exec(html))) {
                return [context.createElement(parsed[1])];
            }
            if ((parsed = jqLiteBuildFragment(html, context))) {
                return parsed.childNodes;
            }
            return [];
        }
    
        function jqLiteWrapNode(node, wrapper) {
            var parent = node.parentNode;
            if (parent) {
                parent.replaceChild(wrapper, node);
            }
            wrapper.appendChild(node);
        }
        var jqLiteContains = Node.prototype.contains || function(arg) {
            return !!(this.compareDocumentPosition(arg) & 16);
        };
    
        function JQLite(element) {
            if (element instanceof JQLite) {
                return element;
            }
            var argIsString;
            if (isString(element)) {
                element = trim(element);
                argIsString = true;
            }
            if (!(this instanceof JQLite)) {
                if (argIsString && element.charAt(0) != '<') {
                    throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
                }
                return new JQLite(element);
            }
            if (argIsString) {
                jqLiteAddNodes(this, jqLiteParseHTML(element));
            } else {
                jqLiteAddNodes(this, element);
            }
        }
    
        function jqLiteClone(element) {
            return element.cloneNode(true);
        }
    
        function jqLiteDealoc(element, onlyDescendants) {
            if (!onlyDescendants) jqLiteRemoveData(element);
            if (element.querySelectorAll) {
                var descendants = element.querySelectorAll('*');
                for (var i = 0, l = descendants.length; i < l; i++) {
                    jqLiteRemoveData(descendants[i]);
                }
            }
        }
    
        function jqLiteOff(element, type, fn, unsupported) {
            if (isDefined(unsupported)) throw jqLiteMinErr('offargs', 'jqLite#off() does not support the `selector` argument');
            var expandoStore = jqLiteExpandoStore(element);
            var events = expandoStore && expandoStore.events;
            var handle = expandoStore && expandoStore.handle;
            if (!handle) return;
            if (!type) {
                for (type in events) {
                    if (type !== '$destroy') {
                        removeEventListenerFn(element, type, handle);
                    }
                    delete events[type];
                }
            } else {
                var removeHandler = function(type) {
                    var listenerFns = events[type];
                    if (isDefined(fn)) {
                        arrayRemove(listenerFns || [], fn);
                    }
                    if (!(isDefined(fn) && listenerFns && listenerFns.length > 0)) {
                        removeEventListenerFn(element, type, handle);
                        delete events[type];
                    }
                };
                forEach(type.split(' '), function(type) {
                    removeHandler(type);
                    if (MOUSE_EVENT_MAP[type]) {
                        removeHandler(MOUSE_EVENT_MAP[type]);
                    }
                });
            }
        }
    
        function jqLiteRemoveData(element, name) {
            var expandoId = element.ng339;
            var expandoStore = expandoId && jqCache[expandoId];
            if (expandoStore) {
                if (name) {
                    delete expandoStore.data[name];
                    return;
                }
                if (expandoStore.handle) {
                    if (expandoStore.events.$destroy) {
                        expandoStore.handle({}, '$destroy');
                    }
                    jqLiteOff(element);
                }
                delete jqCache[expandoId];
                element.ng339 = undefined;
            }
        }
    
        function jqLiteExpandoStore(element, createIfNecessary) {
            var expandoId = element.ng339,
                expandoStore = expandoId && jqCache[expandoId];
            if (createIfNecessary && !expandoStore) {
                element.ng339 = expandoId = jqNextId();
                expandoStore = jqCache[expandoId] = {
                    events: {},
                    data: {},
                    handle: undefined
                };
            }
            return expandoStore;
        }
    
        function jqLiteData(element, key, value) {
            if (jqLiteAcceptsData(element)) {
                var isSimpleSetter = isDefined(value);
                var isSimpleGetter = !isSimpleSetter && key && !isObject(key);
                var massGetter = !key;
                var expandoStore = jqLiteExpandoStore(element, !isSimpleGetter);
                var data = expandoStore && expandoStore.data;
                if (isSimpleSetter) {
                    data[key] = value;
                } else {
                    if (massGetter) {
                        return data;
                    } else {
                        if (isSimpleGetter) {
                            return data && data[key];
                        } else {
                            extend(data, key);
                        }
                    }
                }
            }
        }
    
        function jqLiteHasClass(element, selector) {
            if (!element.getAttribute) return false;
            return ((" " + (element.getAttribute('class') || '') + " ").replace(/[\n\t]/g, " ").indexOf(" " + selector + " ") > -1);
        }
    
        function jqLiteRemoveClass(element, cssClasses) {
            if (cssClasses && element.setAttribute) {
                forEach(cssClasses.split(' '), function(cssClass) {
                    element.setAttribute('class', trim(
                        (" " + (element.getAttribute('class') || '') + " ")
                        .replace(/[\n\t]/g, " ")
                        .replace(" " + trim(cssClass) + " ", " ")));
                });
            }
        }
    
        function jqLiteAddClass(element, cssClasses) {
            if (cssClasses && element.setAttribute) {
                var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ')
                    .replace(/[\n\t]/g, " ");
                forEach(cssClasses.split(' '), function(cssClass) {
                    cssClass = trim(cssClass);
                    if (existingClasses.indexOf(' ' + cssClass + ' ') === -1) {
                        existingClasses += cssClass + ' ';
                    }
                });
                element.setAttribute('class', trim(existingClasses));
            }
        }
    
        function jqLiteAddNodes(root, elements) {
            if (elements) {
                if (elements.nodeType) {
                    root[root.length++] = elements;
                } else {
                    var length = elements.length;
                    if (typeof length === 'number' && elements.window !== elements) {
                        if (length) {
                            for (var i = 0; i < length; i++) {
                                root[root.length++] = elements[i];
                            }
                        }
                    } else {
                        root[root.length++] = elements;
                    }
                }
            }
        }
    
        function jqLiteController(element, name) {
            return jqLiteInheritedData(element, '$' + (name || 'ngController') + 'Controller');
        }
    
        function jqLiteInheritedData(element, name, value) {
            if (element.nodeType == NODE_TYPE_DOCUMENT) {
                element = element.documentElement;
            }
            var names = isArray(name) ? name : [name];
            while (element) {
                for (var i = 0, ii = names.length; i < ii; i++) {
                    if (isDefined(value = jqLite.data(element, names[i]))) return value;
                }
                element = element.parentNode || (element.nodeType === NODE_TYPE_DOCUMENT_FRAGMENT && element.host);
            }
        }
    
        function jqLiteEmpty(element) {
            jqLiteDealoc(element, true);
            while (element.firstChild) {
                element.removeChild(element.firstChild);
            }
        }
    
        function jqLiteRemove(element, keepData) {
            if (!keepData) jqLiteDealoc(element);
            var parent = element.parentNode;
            if (parent) parent.removeChild(element);
        }
    
        function jqLiteDocumentLoaded(action, win) {
            win = win || window;
            if (win.document.readyState === 'complete') {
                win.setTimeout(action);
            } else {
                jqLite(win).on('load', action);
            }
        }
        var JQLitePrototype = JQLite.prototype = {
            ready: function(fn) {
                var fired = false;
    
                function trigger() {
                    if (fired) return;
                    fired = true;
                    fn();
                }
                if (document.readyState === 'complete') {
                    setTimeout(trigger);
                } else {
                    this.on('DOMContentLoaded', trigger);
                    JQLite(window).on('load', trigger);
                }
            },
            toString: function() {
                var value = [];
                forEach(this, function(e) {
                    value.push('' + e);
                });
                return '[' + value.join(', ') + ']';
            },
            eq: function(index) {
                return (index >= 0) ? jqLite(this[index]) : jqLite(this[this.length + index]);
            },
            length: 0,
            push: push,
            sort: [].sort,
            splice: [].splice
        };
        var BOOLEAN_ATTR = {};
        forEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','), function(value) {
            BOOLEAN_ATTR[lowercase(value)] = value;
        });
        var BOOLEAN_ELEMENTS = {};
        forEach('input,select,option,textarea,button,form,details'.split(','), function(value) {
            BOOLEAN_ELEMENTS[value] = true;
        });
        var ALIASED_ATTR = {
            'ngMinlength': 'minlength',
            'ngMaxlength': 'maxlength',
            'ngMin': 'min',
            'ngMax': 'max',
            'ngPattern': 'pattern'
        };
    
        function getBooleanAttrName(element, name) {
            var booleanAttr = BOOLEAN_ATTR[name.toLowerCase()];
            return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr;
        }
    
        function getAliasedAttrName(name) {
            return ALIASED_ATTR[name];
        }
        forEach({
            data: jqLiteData,
            removeData: jqLiteRemoveData,
            hasData: jqLiteHasData,
            cleanData: jqLiteCleanData
        }, function(fn, name) {
            JQLite[name] = fn;
        });
        forEach({
            data: jqLiteData,
            inheritedData: jqLiteInheritedData,
            scope: function(element) {
                return jqLite.data(element, '$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']);
            },
            isolateScope: function(element) {
                return jqLite.data(element, '$isolateScope') || jqLite.data(element, '$isolateScopeNoTemplate');
            },
            controller: jqLiteController,
            injector: function(element) {
                return jqLiteInheritedData(element, '$injector');
            },
            removeAttr: function(element, name) {
                element.removeAttribute(name);
            },
            hasClass: jqLiteHasClass,
            css: function(element, name, value) {
                name = camelCase(name);
                if (isDefined(value)) {
                    element.style[name] = value;
                } else {
                    return element.style[name];
                }
            },
            attr: function(element, name, value) {
                var nodeType = element.nodeType;
                if (nodeType === NODE_TYPE_TEXT || nodeType === NODE_TYPE_ATTRIBUTE || nodeType === NODE_TYPE_COMMENT) {
                    return;
                }
                var lowercasedName = lowercase(name);
                if (BOOLEAN_ATTR[lowercasedName]) {
                    if (isDefined(value)) {
                        if (!!value) {
                            element[name] = true;
                            element.setAttribute(name, lowercasedName);
                        } else {
                            element[name] = false;
                            element.removeAttribute(lowercasedName);
                        }
                    } else {
                        return (element[name] ||
                                (element.attributes.getNamedItem(name) || noop).specified) ?
                            lowercasedName :
                            undefined;
                    }
                } else if (isDefined(value)) {
                    element.setAttribute(name, value);
                } else if (element.getAttribute) {
                    var ret = element.getAttribute(name, 2);
                    return ret === null ? undefined : ret;
                }
            },
            prop: function(element, name, value) {
                if (isDefined(value)) {
                    element[name] = value;
                } else {
                    return element[name];
                }
            },
            text: (function() {
                getText.$dv = '';
                return getText;
    
                function getText(element, value) {
                    if (isUndefined(value)) {
                        var nodeType = element.nodeType;
                        return (nodeType === NODE_TYPE_ELEMENT || nodeType === NODE_TYPE_TEXT) ? element.textContent : '';
                    }
                    element.textContent = value;
                }
            })(),
            val: function(element, value) {
                if (isUndefined(value)) {
                    if (element.multiple && nodeName_(element) === 'select') {
                        var result = [];
                        forEach(element.options, function(option) {
                            if (option.selected) {
                                result.push(option.value || option.text);
                            }
                        });
                        return result.length === 0 ? null : result;
                    }
                    return element.value;
                }
                element.value = value;
            },
            html: function(element, value) {
                if (isUndefined(value)) {
                    return element.innerHTML;
                }
                jqLiteDealoc(element, true);
                element.innerHTML = value;
            },
            empty: jqLiteEmpty
        }, function(fn, name) {
            JQLite.prototype[name] = function(arg1, arg2) {
                var i, key;
                var nodeCount = this.length;
                if (fn !== jqLiteEmpty &&
                    (isUndefined((fn.length == 2 && (fn !== jqLiteHasClass && fn !== jqLiteController)) ? arg1 : arg2))) {
                    if (isObject(arg1)) {
                        for (i = 0; i < nodeCount; i++) {
                            if (fn === jqLiteData) {
                                fn(this[i], arg1);
                            } else {
                                for (key in arg1) {
                                    fn(this[i], key, arg1[key]);
                                }
                            }
                        }
                        return this;
                    } else {
                        var value = fn.$dv;
                        var jj = (isUndefined(value)) ? Math.min(nodeCount, 1) : nodeCount;
                        for (var j = 0; j < jj; j++) {
                            var nodeValue = fn(this[j], arg1, arg2);
                            value = value ? value + nodeValue : nodeValue;
                        }
                        return value;
                    }
                } else {
                    for (i = 0; i < nodeCount; i++) {
                        fn(this[i], arg1, arg2);
                    }
                    return this;
                }
            };
        });
    
        function createEventHandler(element, events) {
            var eventHandler = function(event, type) {
                event.isDefaultPrevented = function() {
                    return event.defaultPrevented;
                };
                var eventFns = events[type || event.type];
                var eventFnsLength = eventFns ? eventFns.length : 0;
                if (!eventFnsLength) return;
                if (isUndefined(event.immediatePropagationStopped)) {
                    var originalStopImmediatePropagation = event.stopImmediatePropagation;
                    event.stopImmediatePropagation = function() {
                        event.immediatePropagationStopped = true;
                        if (event.stopPropagation) {
                            event.stopPropagation();
                        }
                        if (originalStopImmediatePropagation) {
                            originalStopImmediatePropagation.call(event);
                        }
                    };
                }
                event.isImmediatePropagationStopped = function() {
                    return event.immediatePropagationStopped === true;
                };
                var handlerWrapper = eventFns.specialHandlerWrapper || defaultHandlerWrapper;
                if ((eventFnsLength > 1)) {
                    eventFns = shallowCopy(eventFns);
                }
                for (var i = 0; i < eventFnsLength; i++) {
                    if (!event.isImmediatePropagationStopped()) {
                        handlerWrapper(element, event, eventFns[i]);
                    }
                }
            };
            eventHandler.elem = element;
            return eventHandler;
        }
    
        function defaultHandlerWrapper(element, event, handler) {
            handler.call(element, event);
        }
    
        function specialMouseHandlerWrapper(target, event, handler) {
            var related = event.relatedTarget;
            if (!related || (related !== target && !jqLiteContains.call(target, related))) {
                handler.call(target, event);
            }
        }
        forEach({
            removeData: jqLiteRemoveData,
            on: function jqLiteOn(element, type, fn, unsupported) {
                if (isDefined(unsupported)) throw jqLiteMinErr('onargs', 'jqLite#on() does not support the `selector` or `eventData` parameters');
                if (!jqLiteAcceptsData(element)) {
                    return;
                }
                var expandoStore = jqLiteExpandoStore(element, true);
                var events = expandoStore.events;
                var handle = expandoStore.handle;
                if (!handle) {
                    handle = expandoStore.handle = createEventHandler(element, events);
                }
                var types = type.indexOf(' ') >= 0 ? type.split(' ') : [type];
                var i = types.length;
                var addHandler = function(type, specialHandlerWrapper, noEventListener) {
                    var eventFns = events[type];
                    if (!eventFns) {
                        eventFns = events[type] = [];
                        eventFns.specialHandlerWrapper = specialHandlerWrapper;
                        if (type !== '$destroy' && !noEventListener) {
                            addEventListenerFn(element, type, handle);
                        }
                    }
                    eventFns.push(fn);
                };
                while (i--) {
                    type = types[i];
                    if (MOUSE_EVENT_MAP[type]) {
                        addHandler(MOUSE_EVENT_MAP[type], specialMouseHandlerWrapper);
                        addHandler(type, undefined, true);
                    } else {
                        addHandler(type);
                    }
                }
            },
            off: jqLiteOff,
            one: function(element, type, fn) {
                element = jqLite(element);
                element.on(type, function onFn() {
                    element.off(type, fn);
                    element.off(type, onFn);
                });
                element.on(type, fn);
            },
            replaceWith: function(element, replaceNode) {
                var index, parent = element.parentNode;
                jqLiteDealoc(element);
                forEach(new JQLite(replaceNode), function(node) {
                    if (index) {
                        parent.insertBefore(node, index.nextSibling);
                    } else {
                        parent.replaceChild(node, element);
                    }
                    index = node;
                });
            },
            children: function(element) {
                var children = [];
                forEach(element.childNodes, function(element) {
                    if (element.nodeType === NODE_TYPE_ELEMENT) {
                        children.push(element);
                    }
                });
                return children;
            },
            contents: function(element) {
                return element.contentDocument || element.childNodes || [];
            },
            append: function(element, node) {
                var nodeType = element.nodeType;
                if (nodeType !== NODE_TYPE_ELEMENT && nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT) return;
                node = new JQLite(node);
                for (var i = 0, ii = node.length; i < ii; i++) {
                    var child = node[i];
                    element.appendChild(child);
                }
            },
            prepend: function(element, node) {
                if (element.nodeType === NODE_TYPE_ELEMENT) {
                    var index = element.firstChild;
                    forEach(new JQLite(node), function(child) {
                        element.insertBefore(child, index);
                    });
                }
            },
            wrap: function(element, wrapNode) {
                jqLiteWrapNode(element, jqLite(wrapNode).eq(0).clone()[0]);
            },
            remove: jqLiteRemove,
            detach: function(element) {
                jqLiteRemove(element, true);
            },
            after: function(element, newElement) {
                var index = element,
                    parent = element.parentNode;
                newElement = new JQLite(newElement);
                for (var i = 0, ii = newElement.length; i < ii; i++) {
                    var node = newElement[i];
                    parent.insertBefore(node, index.nextSibling);
                    index = node;
                }
            },
            addClass: jqLiteAddClass,
            removeClass: jqLiteRemoveClass,
            toggleClass: function(element, selector, condition) {
                if (selector) {
                    forEach(selector.split(' '), function(className) {
                        var classCondition = condition;
                        if (isUndefined(classCondition)) {
                            classCondition = !jqLiteHasClass(element, className);
                        }
                        (classCondition ? jqLiteAddClass : jqLiteRemoveClass)(element, className);
                    });
                }
            },
            parent: function(element) {
                var parent = element.parentNode;
                return parent && parent.nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT ? parent : null;
            },
            next: function(element) {
                return element.nextElementSibling;
            },
            find: function(element, selector) {
                if (element.getElementsByTagName) {
                    return element.getElementsByTagName(selector);
                } else {
                    return [];
                }
            },
            clone: jqLiteClone,
            triggerHandler: function(element, event, extraParameters) {
                var dummyEvent, eventFnsCopy, handlerArgs;
                var eventName = event.type || event;
                var expandoStore = jqLiteExpandoStore(element);
                var events = expandoStore && expandoStore.events;
                var eventFns = events && events[eventName];
                if (eventFns) {
                    dummyEvent = {
                        preventDefault: function() {
                            this.defaultPrevented = true;
                        },
                        isDefaultPrevented: function() {
                            return this.defaultPrevented === true;
                        },
                        stopImmediatePropagation: function() {
                            this.immediatePropagationStopped = true;
                        },
                        isImmediatePropagationStopped: function() {
                            return this.immediatePropagationStopped === true;
                        },
                        stopPropagation: noop,
                        type: eventName,
                        target: element
                    };
                    if (event.type) {
                        dummyEvent = extend(dummyEvent, event);
                    }
                    eventFnsCopy = shallowCopy(eventFns);
                    handlerArgs = extraParameters ? [dummyEvent].concat(extraParameters) : [dummyEvent];
                    forEach(eventFnsCopy, function(fn) {
                        if (!dummyEvent.isImmediatePropagationStopped()) {
                            fn.apply(element, handlerArgs);
                        }
                    });
                }
            }
        }, function(fn, name) {
            JQLite.prototype[name] = function(arg1, arg2, arg3) {
                var value;
                for (var i = 0, ii = this.length; i < ii; i++) {
                    if (isUndefined(value)) {
                        value = fn(this[i], arg1, arg2, arg3);
                        if (isDefined(value)) {
                            value = jqLite(value);
                        }
                    } else {
                        jqLiteAddNodes(value, fn(this[i], arg1, arg2, arg3));
                    }
                }
                return isDefined(value) ? value : this;
            };
            JQLite.prototype.bind = JQLite.prototype.on;
            JQLite.prototype.unbind = JQLite.prototype.off;
        });
    
        function $$jqLiteProvider() {
            this.$get = function $$jqLite() {
                return extend(JQLite, {
                    hasClass: function(node, classes) {
                        if (node.attr) node = node[0];
                        return jqLiteHasClass(node, classes);
                    },
                    addClass: function(node, classes) {
                        if (node.attr) node = node[0];
                        return jqLiteAddClass(node, classes);
                    },
                    removeClass: function(node, classes) {
                        if (node.attr) node = node[0];
                        return jqLiteRemoveClass(node, classes);
                    }
                });
            };
        }
    
        function hashKey(obj, nextUidFn) {
            var key = obj && obj.$$hashKey;
            if (key) {
                if (typeof key === 'function') {
                    key = obj.$$hashKey();
                }
                return key;
            }
            var objType = typeof obj;
            if (objType == 'function' || (objType == 'object' && obj !== null)) {
                key = obj.$$hashKey = objType + ':' + (nextUidFn || nextUid)();
            } else {
                key = objType + ':' + obj;
            }
            return key;
        }
    
        function HashMap(array, isolatedUid) {
            if (isolatedUid) {
                var uid = 0;
                this.nextUid = function() {
                    return ++uid;
                };
            }
            forEach(array, this.put, this);
        }
        HashMap.prototype = {
            put: function(key, value) {
                this[hashKey(key, this.nextUid)] = value;
            },
            get: function(key) {
                return this[hashKey(key, this.nextUid)];
            },
            remove: function(key) {
                var value = this[key = hashKey(key, this.nextUid)];
                delete this[key];
                return value;
            }
        };
        var $$HashMapProvider = [function() {
            this.$get = [function() {
                return HashMap;
            }];
        }];
        var ARROW_ARG = /^([^\(]+?)=>/;
        var FN_ARGS = /^[^\(]*\(\s*([^\)]*)\)/m;
        var FN_ARG_SPLIT = /,/;
        var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
        var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
        var $injectorMinErr = minErr('$injector');
    
        function extractArgs(fn) {
            var fnText = fn.toString().replace(STRIP_COMMENTS, ''),
                args = fnText.match(ARROW_ARG) || fnText.match(FN_ARGS);
            return args;
        }
    
        function anonFn(fn) {
            var args = extractArgs(fn);
            if (args) {
                return 'function(' + (args[1] || '').replace(/[\s\r\n]+/, ' ') + ')';
            }
            return 'fn';
        }
    
        function annotate(fn, strictDi, name) {
            var $inject,
                argDecl,
                last;
            if (typeof fn === 'function') {
                if (!($inject = fn.$inject)) {
                    $inject = [];
                    if (fn.length) {
                        if (strictDi) {
                            if (!isString(name) || !name) {
                                name = fn.name || anonFn(fn);
                            }
                            throw $injectorMinErr('strictdi',
                                '{0} is not using explicit annotation and cannot be invoked in strict mode', name);
                        }
                        argDecl = extractArgs(fn);
                        forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) {
                            arg.replace(FN_ARG, function(all, underscore, name) {
                                $inject.push(name);
                            });
                        });
                    }
                    fn.$inject = $inject;
                }
            } else if (isArray(fn)) {
                last = fn.length - 1;
                assertArgFn(fn[last], 'fn');
                $inject = fn.slice(0, last);
            } else {
                assertArgFn(fn, 'fn', true);
            }
            return $inject;
        }
    
        function createInjector(modulesToLoad, strictDi) {
            strictDi = (strictDi === true);
            var INSTANTIATING = {},
                providerSuffix = 'Provider',
                path = [],
                loadedModules = new HashMap([], true),
                providerCache = {
                    $provide: {
                        provider: supportObject(provider),
                        factory: supportObject(factory),
                        service: supportObject(service),
                        value: supportObject(value),
                        constant: supportObject(constant),
                        decorator: decorator
                    }
                },
                providerInjector = (providerCache.$injector =
                    createInternalInjector(providerCache, function(serviceName, caller) {
                        if (angular.isString(caller)) {
                            path.push(caller);
                        }
                        throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- '));
                    })),
                instanceCache = {},
                protoInstanceInjector =
                createInternalInjector(instanceCache, function(serviceName, caller) {
                    var provider = providerInjector.get(serviceName + providerSuffix, caller);
                    return instanceInjector.invoke(
                        provider.$get, provider, undefined, serviceName);
                }),
                instanceInjector = protoInstanceInjector;
            providerCache['$injector' + providerSuffix] = {
                $get: valueFn(protoInstanceInjector)
            };
            var runBlocks = loadModules(modulesToLoad);
            instanceInjector = protoInstanceInjector.get('$injector');
            instanceInjector.strictDi = strictDi;
            forEach(runBlocks, function(fn) {
                if (fn) instanceInjector.invoke(fn);
            });
            return instanceInjector;
    
            function supportObject(delegate) {
                return function(key, value) {
                    if (isObject(key)) {
                        forEach(key, reverseParams(delegate));
                    } else {
                        return delegate(key, value);
                    }
                };
            }
    
            function provider(name, provider_) {
                assertNotHasOwnProperty(name, 'service');
                if (isFunction(provider_) || isArray(provider_)) {
                    provider_ = providerInjector.instantiate(provider_);
                }
                if (!provider_.$get) {
                    throw $injectorMinErr('pget', "Provider '{0}' must define $get factory method.", name);
                }
                return providerCache[name + providerSuffix] = provider_;
            }
    
            function enforceReturnValue(name, factory) {
                return function enforcedReturnValue() {
                    var result = instanceInjector.invoke(factory, this);
                    if (isUndefined(result)) {
                        throw $injectorMinErr('undef', "Provider '{0}' must return a value from $get factory method.", name);
                    }
                    return result;
                };
            }
    
            function factory(name, factoryFn, enforce) {
                return provider(name, {
                    $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
                });
            }
    
            function service(name, constructor) {
                return factory(name, ['$injector', function($injector) {
                    return $injector.instantiate(constructor);
                }]);
            }
    
            function value(name, val) {
                return factory(name, valueFn(val), false);
            }
    
            function constant(name, value) {
                assertNotHasOwnProperty(name, 'constant');
                providerCache[name] = value;
                instanceCache[name] = value;
            }
    
            function decorator(serviceName, decorFn) {
                var origProvider = providerInjector.get(serviceName + providerSuffix),
                    orig$get = origProvider.$get;
                origProvider.$get = function() {
                    var origInstance = instanceInjector.invoke(orig$get, origProvider);
                    return instanceInjector.invoke(decorFn, null, {
                        $delegate: origInstance
                    });
                };
            }
    
            function loadModules(modulesToLoad) {
                assertArg(isUndefined(modulesToLoad) || isArray(modulesToLoad), 'modulesToLoad', 'not an array');
                var runBlocks = [],
                    moduleFn;
                forEach(modulesToLoad, function(module) {
                    if (loadedModules.get(module)) return;
                    loadedModules.put(module, true);
    
                    function runInvokeQueue(queue) {
                        var i, ii;
                        for (i = 0, ii = queue.length; i < ii; i++) {
                            var invokeArgs = queue[i],
                                provider = providerInjector.get(invokeArgs[0]);
                            provider[invokeArgs[1]].apply(provider, invokeArgs[2]);
                        }
                    }
                    try {
                        if (isString(module)) {
                            moduleFn = angularModule(module);
                            runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks);
                            runInvokeQueue(moduleFn._invokeQueue);
                            runInvokeQueue(moduleFn._configBlocks);
                        } else if (isFunction(module)) {
                            runBlocks.push(providerInjector.invoke(module));
                        } else if (isArray(module)) {
                            runBlocks.push(providerInjector.invoke(module));
                        } else {
                            assertArgFn(module, 'module');
                        }
                    } catch (e) {
                        if (isArray(module)) {
                            module = module[module.length - 1];
                        }
                        if (e.message && e.stack && e.stack.indexOf(e.message) == -1) {
                            e = e.message + '\n' + e.stack;
                        }
                        throw $injectorMinErr('modulerr', "Failed to instantiate module {0} due to:\n{1}",
                            module, e.stack || e.message || e);
                    }
                });
                return runBlocks;
            }
    
            function createInternalInjector(cache, factory) {
                function getService(serviceName, caller) {
                    if (cache.hasOwnProperty(serviceName)) {
                        if (cache[serviceName] === INSTANTIATING) {
                            throw $injectorMinErr('cdep', 'Circular dependency found: {0}',
                                serviceName + ' <- ' + path.join(' <- '));
                        }
                        return cache[serviceName];
                    } else {
                        try {
                            path.unshift(serviceName);
                            cache[serviceName] = INSTANTIATING;
                            return cache[serviceName] = factory(serviceName, caller);
                        } catch (err) {
                            if (cache[serviceName] === INSTANTIATING) {
                                delete cache[serviceName];
                            }
                            throw err;
                        } finally {
                            path.shift();
                        }
                    }
                }
    
                function injectionArgs(fn, locals, serviceName) {
                    var args = [],
                        $inject = createInjector.$$annotate(fn, strictDi, serviceName);
                    for (var i = 0, length = $inject.length; i < length; i++) {
                        var key = $inject[i];
                        if (typeof key !== 'string') {
                            throw $injectorMinErr('itkn',
                                'Incorrect injection token! Expected service name as string, got {0}', key);
                        }
                        args.push(locals && locals.hasOwnProperty(key) ? locals[key] :
                            getService(key, serviceName));
                    }
                    return args;
                }
    
                function isClass(func) {
                    if (msie <= 11) {
                        return false;
                    }
                    return typeof func === 'function' &&
                        /^(?:class\s|constructor\()/.test(Function.prototype.toString.call(func));
                }
    
                function invoke(fn, self, locals, serviceName) {
                    if (typeof locals === 'string') {
                        serviceName = locals;
                        locals = null;
                    }
                    var args = injectionArgs(fn, locals, serviceName);
                    if (isArray(fn)) {
                        fn = fn[fn.length - 1];
                    }
                    if (!isClass(fn)) {
                        return fn.apply(self, args);
                    } else {
                        args.unshift(null);
                        return new(Function.prototype.bind.apply(fn, args))();
                    }
                }
    
                function instantiate(Type, locals, serviceName) {
                    var ctor = (isArray(Type) ? Type[Type.length - 1] : Type);
                    var args = injectionArgs(Type, locals, serviceName);
                    args.unshift(null);
                    return new(Function.prototype.bind.apply(ctor, args))();
                }
                return {
                    invoke: invoke,
                    instantiate: instantiate,
                    get: getService,
                    annotate: createInjector.$$annotate,
                    has: function(name) {
                        return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name);
                    }
                };
            }
        }
        createInjector.$$annotate = annotate;
    
        function $AnchorScrollProvider() {
            var autoScrollingEnabled = true;
            this.disableAutoScrolling = function() {
                autoScrollingEnabled = false;
            };
            this.$get = ['$window', '$location', '$rootScope', function($window, $location, $rootScope) {
                var document = $window.document;
    
                function getFirstAnchor(list) {
                    var result = null;
                    Array.prototype.some.call(list, function(element) {
                        if (nodeName_(element) === 'a') {
                            result = element;
                            return true;
                        }
                    });
                    return result;
                }
    
                function getYOffset() {
                    var offset = scroll.yOffset;
                    if (isFunction(offset)) {
                        offset = offset();
                    } else if (isElement(offset)) {
                        var elem = offset[0];
                        var style = $window.getComputedStyle(elem);
                        if (style.position !== 'fixed') {
                            offset = 0;
                        } else {
                            offset = elem.getBoundingClientRect().bottom;
                        }
                    } else if (!isNumber(offset)) {
                        offset = 0;
                    }
                    return offset;
                }
    
                function scrollTo(elem) {
                    if (elem) {
                        elem.scrollIntoView();
                        var offset = getYOffset();
                        if (offset) {
                            var elemTop = elem.getBoundingClientRect().top;
                            $window.scrollBy(0, elemTop - offset);
                        }
                    } else {
                        $window.scrollTo(0, 0);
                    }
                }
    
                function scroll(hash) {
                    hash = isString(hash) ? hash : $location.hash();
                    var elm;
                    if (!hash) scrollTo(null);
                    else if ((elm = document.getElementById(hash))) scrollTo(elm);
                    else if ((elm = getFirstAnchor(document.getElementsByName(hash)))) scrollTo(elm);
                    else if (hash === 'top') scrollTo(null);
                }
                if (autoScrollingEnabled) {
                    $rootScope.$watch(function autoScrollWatch() {
                            return $location.hash();
                        },
                        function autoScrollWatchAction(newVal, oldVal) {
                            if (newVal === oldVal && newVal === '') return;
                            jqLiteDocumentLoaded(function() {
                                $rootScope.$evalAsync(scroll);
                            });
                        });
                }
                return scroll;
            }];
        }
        var $animateMinErr = minErr('$animate');
        var ELEMENT_NODE = 1;
        var NG_ANIMATE_CLASSNAME = 'ng-animate';
    
        function mergeClasses(a, b) {
            if (!a && !b) return '';
            if (!a) return b;
            if (!b) return a;
            if (isArray(a)) a = a.join(' ');
            if (isArray(b)) b = b.join(' ');
            return a + ' ' + b;
        }
    
        function extractElementNode(element) {
            for (var i = 0; i < element.length; i++) {
                var elm = element[i];
                if (elm.nodeType === ELEMENT_NODE) {
                    return elm;
                }
            }
        }
    
        function splitClasses(classes) {
            if (isString(classes)) {
                classes = classes.split(' ');
            }
            var obj = createMap();
            forEach(classes, function(klass) {
                if (klass.length) {
                    obj[klass] = true;
                }
            });
            return obj;
        }
    
        function prepareAnimateOptions(options) {
            return isObject(options) ?
                options :
                {};
        }
        var $$CoreAnimateJsProvider = function() {
            this.$get = noop;
        };
        var $$CoreAnimateQueueProvider = function() {
            var postDigestQueue = new HashMap();
            var postDigestElements = [];
            this.$get = ['$$AnimateRunner', '$rootScope',
                function($$AnimateRunner, $rootScope) {
                    return {
                        enabled: noop,
                        on: noop,
                        off: noop,
                        pin: noop,
                        push: function(element, event, options, domOperation) {
                            domOperation && domOperation();
                            options = options || {};
                            options.from && element.css(options.from);
                            options.to && element.css(options.to);
                            if (options.addClass || options.removeClass) {
                                addRemoveClassesPostDigest(element, options.addClass, options.removeClass);
                            }
                            var runner = new $$AnimateRunner();
                            runner.complete();
                            return runner;
                        }
                    };
    
                    function updateData(data, classes, value) {
                        var changed = false;
                        if (classes) {
                            classes = isString(classes) ? classes.split(' ') :
                                isArray(classes) ? classes : [];
                            forEach(classes, function(className) {
                                if (className) {
                                    changed = true;
                                    data[className] = value;
                                }
                            });
                        }
                        return changed;
                    }
    
                    function handleCSSClassChanges() {
                        forEach(postDigestElements, function(element) {
                            var data = postDigestQueue.get(element);
                            if (data) {
                                var existing = splitClasses(element.attr('class'));
                                var toAdd = '';
                                var toRemove = '';
                                forEach(data, function(status, className) {
                                    var hasClass = !!existing[className];
                                    if (status !== hasClass) {
                                        if (status) {
                                            toAdd += (toAdd.length ? ' ' : '') + className;
                                        } else {
                                            toRemove += (toRemove.length ? ' ' : '') + className;
                                        }
                                    }
                                });
                                forEach(element, function(elm) {
                                    toAdd && jqLiteAddClass(elm, toAdd);
                                    toRemove && jqLiteRemoveClass(elm, toRemove);
                                });
                                postDigestQueue.remove(element);
                            }
                        });
                        postDigestElements.length = 0;
                    }
    
                    function addRemoveClassesPostDigest(element, add, remove) {
                        var data = postDigestQueue.get(element) || {};
                        var classesAdded = updateData(data, add, true);
                        var classesRemoved = updateData(data, remove, false);
                        if (classesAdded || classesRemoved) {
                            postDigestQueue.put(element, data);
                            postDigestElements.push(element);
                            if (postDigestElements.length === 1) {
                                $rootScope.$$postDigest(handleCSSClassChanges);
                            }
                        }
                    }
                }
            ];
        };
        var $AnimateProvider = ['$provide', function($provide) {
            var provider = this;
            this.$$registeredAnimations = Object.create(null);
            this.register = function(name, factory) {
                if (name && name.charAt(0) !== '.') {
                    throw $animateMinErr('notcsel', "Expecting class selector starting with '.' got '{0}'.", name);
                }
                var key = name + '-animation';
                provider.$$registeredAnimations[name.substr(1)] = key;
                $provide.factory(key, factory);
            };
            this.classNameFilter = function(expression) {
                if (arguments.length === 1) {
                    this.$$classNameFilter = (expression instanceof RegExp) ? expression : null;
                    if (this.$$classNameFilter) {
                        var reservedRegex = new RegExp("(\\s+|\\/)" + NG_ANIMATE_CLASSNAME + "(\\s+|\\/)");
                        if (reservedRegex.test(this.$$classNameFilter.toString())) {
                            throw $animateMinErr('nongcls', '$animateProvider.classNameFilter(regex) prohibits accepting a regex value which matches/contains the "{0}" CSS class.', NG_ANIMATE_CLASSNAME);
                        }
                    }
                }
                return this.$$classNameFilter;
            };
            this.$get = ['$$animateQueue', function($$animateQueue) {
                function domInsert(element, parentElement, afterElement) {
                    if (afterElement) {
                        var afterNode = extractElementNode(afterElement);
                        if (afterNode && !afterNode.parentNode && !afterNode.previousElementSibling) {
                            afterElement = null;
                        }
                    }
                    afterElement ? afterElement.after(element) : parentElement.prepend(element);
                }
                return {
                    on: $$animateQueue.on,
                    off: $$animateQueue.off,
                    pin: $$animateQueue.pin,
                    enabled: $$animateQueue.enabled,
                    cancel: function(runner) {
                        runner.end && runner.end();
                    },
                    enter: function(element, parent, after, options) {
                        parent = parent && jqLite(parent);
                        after = after && jqLite(after);
                        parent = parent || after.parent();
                        domInsert(element, parent, after);
                        return $$animateQueue.push(element, 'enter', prepareAnimateOptions(options));
                    },
                    move: function(element, parent, after, options) {
                        parent = parent && jqLite(parent);
                        after = after && jqLite(after);
                        parent = parent || after.parent();
                        domInsert(element, parent, after);
                        return $$animateQueue.push(element, 'move', prepareAnimateOptions(options));
                    },
                    leave: function(element, options) {
                        return $$animateQueue.push(element, 'leave', prepareAnimateOptions(options), function() {
                            element.remove();
                        });
                    },
                    addClass: function(element, className, options) {
                        options = prepareAnimateOptions(options);
                        options.addClass = mergeClasses(options.addclass, className);
                        return $$animateQueue.push(element, 'addClass', options);
                    },
                    removeClass: function(element, className, options) {
                        options = prepareAnimateOptions(options);
                        options.removeClass = mergeClasses(options.removeClass, className);
                        return $$animateQueue.push(element, 'removeClass', options);
                    },
                    setClass: function(element, add, remove, options) {
                        options = prepareAnimateOptions(options);
                        options.addClass = mergeClasses(options.addClass, add);
                        options.removeClass = mergeClasses(options.removeClass, remove);
                        return $$animateQueue.push(element, 'setClass', options);
                    },
                    animate: function(element, from, to, className, options) {
                        options = prepareAnimateOptions(options);
                        options.from = options.from ? extend(options.from, from) : from;
                        options.to = options.to ? extend(options.to, to) : to;
                        className = className || 'ng-inline-animate';
                        options.tempClasses = mergeClasses(options.tempClasses, className);
                        return $$animateQueue.push(element, 'animate', options);
                    }
                };
            }];
        }];
        var $$AnimateAsyncRunFactoryProvider = function() {
            this.$get = ['$$rAF', function($$rAF) {
                var waitQueue = [];
    
                function waitForTick(fn) {
                    waitQueue.push(fn);
                    if (waitQueue.length > 1) return;
                    $$rAF(function() {
                        for (var i = 0; i < waitQueue.length; i++) {
                            waitQueue[i]();
                        }
                        waitQueue = [];
                    });
                }
                return function() {
                    var passed = false;
                    waitForTick(function() {
                        passed = true;
                    });
                    return function(callback) {
                        passed ? callback() : waitForTick(callback);
                    };
                };
            }];
        };
        var $$AnimateRunnerFactoryProvider = function() {
            this.$get = ['$q', '$sniffer', '$$animateAsyncRun', '$document', '$timeout',
                function($q, $sniffer, $$animateAsyncRun, $document, $timeout) {
                    var INITIAL_STATE = 0;
                    var DONE_PENDING_STATE = 1;
                    var DONE_COMPLETE_STATE = 2;
                    AnimateRunner.chain = function(chain, callback) {
                        var index = 0;
                        next();
    
                        function next() {
                            if (index === chain.length) {
                                callback(true);
                                return;
                            }
                            chain[index](function(response) {
                                if (response === false) {
                                    callback(false);
                                    return;
                                }
                                index++;
                                next();
                            });
                        }
                    };
                    AnimateRunner.all = function(runners, callback) {
                        var count = 0;
                        var status = true;
                        forEach(runners, function(runner) {
                            runner.done(onProgress);
                        });
    
                        function onProgress(response) {
                            status = status && response;
                            if (++count === runners.length) {
                                callback(status);
                            }
                        }
                    };
    
                    function AnimateRunner(host) {
                        this.setHost(host);
                        var rafTick = $$animateAsyncRun();
                        var timeoutTick = function(fn) {
                            $timeout(fn, 0, false);
                        };
                        this._doneCallbacks = [];
                        this._tick = function(fn) {
                            var doc = $document[0];
                            if (doc && doc.hidden) {
                                timeoutTick(fn);
                            } else {
                                rafTick(fn);
                            }
                        };
                        this._state = 0;
                    }
                    AnimateRunner.prototype = {
                        setHost: function(host) {
                            this.host = host || {};
                        },
                        done: function(fn) {
                            if (this._state === DONE_COMPLETE_STATE) {
                                fn();
                            } else {
                                this._doneCallbacks.push(fn);
                            }
                        },
                        progress: noop,
                        getPromise: function() {
                            if (!this.promise) {
                                var self = this;
                                this.promise = $q(function(resolve, reject) {
                                    self.done(function(status) {
                                        status === false ? reject() : resolve();
                                    });
                                });
                            }
                            return this.promise;
                        },
                        then: function(resolveHandler, rejectHandler) {
                            return this.getPromise().then(resolveHandler, rejectHandler);
                        },
                        'catch': function(handler) {
                            return this.getPromise()['catch'](handler);
                        },
                        'finally': function(handler) {
                            return this.getPromise()['finally'](handler);
                        },
                        pause: function() {
                            if (this.host.pause) {
                                this.host.pause();
                            }
                        },
                        resume: function() {
                            if (this.host.resume) {
                                this.host.resume();
                            }
                        },
                        end: function() {
                            if (this.host.end) {
                                this.host.end();
                            }
                            this._resolve(true);
                        },
                        cancel: function() {
                            if (this.host.cancel) {
                                this.host.cancel();
                            }
                            this._resolve(false);
                        },
                        complete: function(response) {
                            var self = this;
                            if (self._state === INITIAL_STATE) {
                                self._state = DONE_PENDING_STATE;
                                self._tick(function() {
                                    self._resolve(response);
                                });
                            }
                        },
                        _resolve: function(response) {
                            if (this._state !== DONE_COMPLETE_STATE) {
                                forEach(this._doneCallbacks, function(fn) {
                                    fn(response);
                                });
                                this._doneCallbacks.length = 0;
                                this._state = DONE_COMPLETE_STATE;
                            }
                        }
                    };
                    return AnimateRunner;
                }
            ];
        };
        var $CoreAnimateCssProvider = function() {
            this.$get = ['$$rAF', '$q', '$$AnimateRunner', function($$rAF, $q, $$AnimateRunner) {
                return function(element, initialOptions) {
                    var options = initialOptions || {};
                    if (!options.$$prepared) {
                        options = copy(options);
                    }
                    if (options.cleanupStyles) {
                        options.from = options.to = null;
                    }
                    if (options.from) {
                        element.css(options.from);
                        options.from = null;
                    }
                    var closed, runner = new $$AnimateRunner();
                    return {
                        start: run,
                        end: run
                    };
    
                    function run() {
                        $$rAF(function() {
                            applyAnimationContents();
                            if (!closed) {
                                runner.complete();
                            }
                            closed = true;
                        });
                        return runner;
                    }
    
                    function applyAnimationContents() {
                        if (options.addClass) {
                            element.addClass(options.addClass);
                            options.addClass = null;
                        }
                        if (options.removeClass) {
                            element.removeClass(options.removeClass);
                            options.removeClass = null;
                        }
                        if (options.to) {
                            element.css(options.to);
                            options.to = null;
                        }
                    }
                };
            }];
        };
    
        function Browser(window, document, $log, $sniffer) {
            var self = this,
                location = window.location,
                history = window.history,
                setTimeout = window.setTimeout,
                clearTimeout = window.clearTimeout,
                pendingDeferIds = {};
            self.isMock = false;
            var outstandingRequestCount = 0;
            var outstandingRequestCallbacks = [];
            self.$$completeOutstandingRequest = completeOutstandingRequest;
            self.$$incOutstandingRequestCount = function() {
                outstandingRequestCount++;
            };
    
            function completeOutstandingRequest(fn) {
                try {
                    fn.apply(null, sliceArgs(arguments, 1));
                } finally {
                    outstandingRequestCount--;
                    if (outstandingRequestCount === 0) {
                        while (outstandingRequestCallbacks.length) {
                            try {
                                outstandingRequestCallbacks.pop()();
                            } catch (e) {
                                $log.error(e);
                            }
                        }
                    }
                }
            }
    
            function getHash(url) {
                var index = url.indexOf('#');
                return index === -1 ? '' : url.substr(index);
            }
            self.notifyWhenNoOutstandingRequests = function(callback) {
                if (outstandingRequestCount === 0) {
                    callback();
                } else {
                    outstandingRequestCallbacks.push(callback);
                }
            };
            var cachedState, lastHistoryState,
                lastBrowserUrl = location.href,
                baseElement = document.find('base'),
                pendingLocation = null,
                getCurrentState = !$sniffer.history ? noop : function getCurrentState() {
                    try {
                        return history.state;
                    } catch (e) {}
                };
            cacheState();
            lastHistoryState = cachedState;
            self.url = function(url, replace, state) {
                if (isUndefined(state)) {
                    state = null;
                }
                if (location !== window.location) location = window.location;
                if (history !== window.history) history = window.history;
                if (url) {
                    var sameState = lastHistoryState === state;
                    if (lastBrowserUrl === url && (!$sniffer.history || sameState)) {
                        return self;
                    }
                    var sameBase = lastBrowserUrl && stripHash(lastBrowserUrl) === stripHash(url);
                    lastBrowserUrl = url;
                    lastHistoryState = state;
                    if ($sniffer.history && (!sameBase || !sameState)) {
                        history[replace ? 'replaceState' : 'pushState'](state, '', url);
                        cacheState();
                        lastHistoryState = cachedState;
                    } else {
                        if (!sameBase || pendingLocation) {
                            pendingLocation = url;
                        }
                        if (replace) {
                            location.replace(url);
                        } else if (!sameBase) {
                            location.href = url;
                        } else {
                            location.hash = getHash(url);
                        }
                        if (location.href !== url) {
                            pendingLocation = url;
                        }
                    }
                    return self;
                } else {
                    return pendingLocation || location.href.replace(/%27/g, "'");
                }
            };
            self.state = function() {
                return cachedState;
            };
            var urlChangeListeners = [],
                urlChangeInit = false;
    
            function cacheStateAndFireUrlChange() {
                pendingLocation = null;
                cacheState();
                fireUrlChange();
            }
            var lastCachedState = null;
    
            function cacheState() {
                cachedState = getCurrentState();
                cachedState = isUndefined(cachedState) ? null : cachedState;
                if (equals(cachedState, lastCachedState)) {
                    cachedState = lastCachedState;
                }
                lastCachedState = cachedState;
            }
    
            function fireUrlChange() {
                if (lastBrowserUrl === self.url() && lastHistoryState === cachedState) {
                    return;
                }
                lastBrowserUrl = self.url();
                lastHistoryState = cachedState;
                forEach(urlChangeListeners, function(listener) {
                    listener(self.url(), cachedState);
                });
            }
            self.onUrlChange = function(callback) {
                if (!urlChangeInit) {
                    if ($sniffer.history) jqLite(window).on('popstate', cacheStateAndFireUrlChange);
                    jqLite(window).on('hashchange', cacheStateAndFireUrlChange);
                    urlChangeInit = true;
                }
                urlChangeListeners.push(callback);
                return callback;
            };
            self.$$applicationDestroyed = function() {
                jqLite(window).off('hashchange popstate', cacheStateAndFireUrlChange);
            };
            self.$$checkUrlChange = fireUrlChange;
            self.baseHref = function() {
                var href = baseElement.attr('href');
                return href ? href.replace(/^(https?\:)?\/\/[^\/]*/, '') : '';
            };
            self.defer = function(fn, delay) {
                var timeoutId;
                outstandingRequestCount++;
                timeoutId = setTimeout(function() {
                    delete pendingDeferIds[timeoutId];
                    completeOutstandingRequest(fn);
                }, delay || 0);
                pendingDeferIds[timeoutId] = true;
                return timeoutId;
            };
            self.defer.cancel = function(deferId) {
                if (pendingDeferIds[deferId]) {
                    delete pendingDeferIds[deferId];
                    clearTimeout(deferId);
                    completeOutstandingRequest(noop);
                    return true;
                }
                return false;
            };
        }
    
        function $BrowserProvider() {
            this.$get = ['$window', '$log', '$sniffer', '$document',
                function($window, $log, $sniffer, $document) {
                    return new Browser($window, $document, $log, $sniffer);
                }
            ];
        }
    
        function $CacheFactoryProvider() {
            this.$get = function() {
                var caches = {};
    
                function cacheFactory(cacheId, options) {
                    if (cacheId in caches) {
                        throw minErr('$cacheFactory')('iid', "CacheId '{0}' is already taken!", cacheId);
                    }
                    var size = 0,
                        stats = extend({}, options, {
                            id: cacheId
                        }),
                        data = createMap(),
                        capacity = (options && options.capacity) || Number.MAX_VALUE,
                        lruHash = createMap(),
                        freshEnd = null,
                        staleEnd = null;
                    return caches[cacheId] = {
                        put: function(key, value) {
                            if (isUndefined(value)) return;
                            if (capacity < Number.MAX_VALUE) {
                                var lruEntry = lruHash[key] || (lruHash[key] = {
                                    key: key
                                });
                                refresh(lruEntry);
                            }
                            if (!(key in data)) size++;
                            data[key] = value;
                            if (size > capacity) {
                                this.remove(staleEnd.key);
                            }
                            return value;
                        },
                        get: function(key) {
                            if (capacity < Number.MAX_VALUE) {
                                var lruEntry = lruHash[key];
                                if (!lruEntry) return;
                                refresh(lruEntry);
                            }
                            return data[key];
                        },
                        remove: function(key) {
                            if (capacity < Number.MAX_VALUE) {
                                var lruEntry = lruHash[key];
                                if (!lruEntry) return;
                                if (lruEntry == freshEnd) freshEnd = lruEntry.p;
                                if (lruEntry == staleEnd) staleEnd = lruEntry.n;
                                link(lruEntry.n, lruEntry.p);
                                delete lruHash[key];
                            }
                            if (!(key in data)) return;
                            delete data[key];
                            size--;
                        },
                        removeAll: function() {
                            data = createMap();
                            size = 0;
                            lruHash = createMap();
                            freshEnd = staleEnd = null;
                        },
                        destroy: function() {
                            data = null;
                            stats = null;
                            lruHash = null;
                            delete caches[cacheId];
                        },
                        info: function() {
                            return extend({}, stats, {
                                size: size
                            });
                        }
                    };
    
                    function refresh(entry) {
                        if (entry != freshEnd) {
                            if (!staleEnd) {
                                staleEnd = entry;
                            } else if (staleEnd == entry) {
                                staleEnd = entry.n;
                            }
                            link(entry.n, entry.p);
                            link(entry, freshEnd);
                            freshEnd = entry;
                            freshEnd.n = null;
                        }
                    }
    
                    function link(nextEntry, prevEntry) {
                        if (nextEntry != prevEntry) {
                            if (nextEntry) nextEntry.p = prevEntry;
                            if (prevEntry) prevEntry.n = nextEntry;
                        }
                    }
                }
                cacheFactory.info = function() {
                    var info = {};
                    forEach(caches, function(cache, cacheId) {
                        info[cacheId] = cache.info();
                    });
                    return info;
                };
                cacheFactory.get = function(cacheId) {
                    return caches[cacheId];
                };
                return cacheFactory;
            };
        }
    
        function $TemplateCacheProvider() {
            this.$get = ['$cacheFactory', function($cacheFactory) {
                return $cacheFactory('templates');
            }];
        }
        var $compileMinErr = minErr('$compile');
        $CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider'];
    
        function $CompileProvider($provide, $$sanitizeUriProvider) {
            var hasDirectives = {},
                Suffix = 'Directive',
                COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\w\-]+)\s+(.*)$/,
                CLASS_DIRECTIVE_REGEXP = /(([\w\-]+)(?:\:([^;]+))?;?)/,
                ALL_OR_NOTHING_ATTRS = makeMap('ngSrc,ngSrcset,src,srcset'),
                REQUIRE_PREFIX_REGEXP = /^(?:(\^\^?)?(\?)?(\^\^?)?)?/;
            var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
            var bindingCache = createMap();
    
            function parseIsolateBindings(scope, directiveName, isController) {
                var LOCAL_REGEXP = /^\s*([@&<]|=(\*?))(\??)\s*(\w*)\s*$/;
                var bindings = {};
                forEach(scope, function(definition, scopeName) {
                    if (definition in bindingCache) {
                        bindings[scopeName] = bindingCache[definition];
                        return;
                    }
                    var match = definition.match(LOCAL_REGEXP);
                    if (!match) {
                        throw $compileMinErr('iscp',
                            "Invalid {3} for directive '{0}'." +
                            " Definition: {... {1}: '{2}' ...}",
                            directiveName, scopeName, definition,
                            (isController ? "controller bindings definition" :
                                "isolate scope definition"));
                    }
                    bindings[scopeName] = {
                        mode: match[1][0],
                        collection: match[2] === '*',
                        optional: match[3] === '?',
                        attrName: match[4] || scopeName
                    };
                    if (match[4]) {
                        bindingCache[definition] = bindings[scopeName];
                    }
                });
                return bindings;
            }
    
            function parseDirectiveBindings(directive, directiveName) {
                var bindings = {
                    isolateScope: null,
                    bindToController: null
                };
                if (isObject(directive.scope)) {
                    if (directive.bindToController === true) {
                        bindings.bindToController = parseIsolateBindings(directive.scope,
                            directiveName, true);
                        bindings.isolateScope = {};
                    } else {
                        bindings.isolateScope = parseIsolateBindings(directive.scope,
                            directiveName, false);
                    }
                }
                if (isObject(directive.bindToController)) {
                    bindings.bindToController =
                        parseIsolateBindings(directive.bindToController, directiveName, true);
                }
                if (isObject(bindings.bindToController)) {
                    var controller = directive.controller;
                    var controllerAs = directive.controllerAs;
                    if (!controller) {
                        throw $compileMinErr('noctrl',
                            "Cannot bind to controller without directive '{0}'s controller.",
                            directiveName);
                    } else if (!identifierForController(controller, controllerAs)) {
                        throw $compileMinErr('noident',
                            "Cannot bind to controller without identifier for directive '{0}'.",
                            directiveName);
                    }
                }
                return bindings;
            }
    
            function assertValidDirectiveName(name) {
                var letter = name.charAt(0);
                if (!letter || letter !== lowercase(letter)) {
                    throw $compileMinErr('baddir', "Directive/Component name '{0}' is invalid. The first character must be a lowercase letter", name);
                }
                if (name !== name.trim()) {
                    throw $compileMinErr('baddir',
                        "Directive/Component name '{0}' is invalid. The name should not contain leading or trailing whitespaces",
                        name);
                }
            }
            this.directive = function registerDirective(name, directiveFactory) {
                assertNotHasOwnProperty(name, 'directive');
                if (isString(name)) {
                    assertValidDirectiveName(name);
                    assertArg(directiveFactory, 'directiveFactory');
                    if (!hasDirectives.hasOwnProperty(name)) {
                        hasDirectives[name] = [];
                        $provide.factory(name + Suffix, ['$injector', '$exceptionHandler',
                            function($injector, $exceptionHandler) {
                                var directives = [];
                                forEach(hasDirectives[name], function(directiveFactory, index) {
                                    try {
                                        var directive = $injector.invoke(directiveFactory);
                                        if (isFunction(directive)) {
                                            directive = {
                                                compile: valueFn(directive)
                                            };
                                        } else if (!directive.compile && directive.link) {
                                            directive.compile = valueFn(directive.link);
                                        }
                                        directive.priority = directive.priority || 0;
                                        directive.index = index;
                                        directive.name = directive.name || name;
                                        directive.require = directive.require || (directive.controller && directive.name);
                                        directive.restrict = directive.restrict || 'EA';
                                        directive.$$moduleName = directiveFactory.$$moduleName;
                                        directives.push(directive);
                                    } catch (e) {
                                        $exceptionHandler(e);
                                    }
                                });
                                return directives;
                            }
                        ]);
                    }
                    hasDirectives[name].push(directiveFactory);
                } else {
                    forEach(name, reverseParams(registerDirective));
                }
                return this;
            };
            this.component = function registerComponent(name, options) {
                var controller = options.controller || noop;
    
                function factory($injector) {
                    function makeInjectable(fn) {
                        if (isFunction(fn) || isArray(fn)) {
                            return function(tElement, tAttrs) {
                                return $injector.invoke(fn, this, {
                                    $element: tElement,
                                    $attrs: tAttrs
                                });
                            };
                        } else {
                            return fn;
                        }
                    }
                    var template = (!options.template && !options.templateUrl ? '' : options.template);
                    return {
                        controller: controller,
                        controllerAs: identifierForController(options.controller) || options.controllerAs || '$ctrl',
                        template: makeInjectable(template),
                        templateUrl: makeInjectable(options.templateUrl),
                        transclude: options.transclude,
                        scope: {},
                        bindToController: options.bindings || {},
                        restrict: 'E',
                        require: options.require
                    };
                }
                forEach(options, function(val, key) {
                    if (key.charAt(0) === '$') {
                        factory[key] = val;
                        controller[key] = val;
                    }
                });
                factory.$inject = ['$injector'];
                return this.directive(name, factory);
            };
            this.aHrefSanitizationWhitelist = function(regexp) {
                if (isDefined(regexp)) {
                    $$sanitizeUriProvider.aHrefSanitizationWhitelist(regexp);
                    return this;
                } else {
                    return $$sanitizeUriProvider.aHrefSanitizationWhitelist();
                }
            };
            this.imgSrcSanitizationWhitelist = function(regexp) {
                if (isDefined(regexp)) {
                    $$sanitizeUriProvider.imgSrcSanitizationWhitelist(regexp);
                    return this;
                } else {
                    return $$sanitizeUriProvider.imgSrcSanitizationWhitelist();
                }
            };
            var debugInfoEnabled = true;
            this.debugInfoEnabled = function(enabled) {
                if (isDefined(enabled)) {
                    debugInfoEnabled = enabled;
                    return this;
                }
                return debugInfoEnabled;
            };
            var TTL = 10;
            this.onChangesTtl = function(value) {
                if (arguments.length) {
                    TTL = value;
                    return this;
                }
                return TTL;
            };
            this.$get = [
                '$injector', '$interpolate', '$exceptionHandler', '$templateRequest', '$parse',
                '$controller', '$rootScope', '$sce', '$animate', '$$sanitizeUri',
                function($injector, $interpolate, $exceptionHandler, $templateRequest, $parse,
                    $controller, $rootScope, $sce, $animate, $$sanitizeUri) {
                    var SIMPLE_ATTR_NAME = /^\w/;
                    var specialAttrHolder = document.createElement('div');
                    var onChangesTtl = TTL;
                    var onChangesQueue;
    
                    function flushOnChangesQueue() {
                        try {
                            if (!(--onChangesTtl)) {
                                onChangesQueue = undefined;
                                throw $compileMinErr('infchng', '{0} $onChanges() iterations reached. Aborting!\n', TTL);
                            }
                            $rootScope.$apply(function() {
                                for (var i = 0, ii = onChangesQueue.length; i < ii; ++i) {
                                    onChangesQueue[i]();
                                }
                                onChangesQueue = undefined;
                            });
                        } finally {
                            onChangesTtl++;
                        }
                    }
    
                    function Attributes(element, attributesToCopy) {
                        if (attributesToCopy) {
                            var keys = Object.keys(attributesToCopy);
                            var i, l, key;
                            for (i = 0, l = keys.length; i < l; i++) {
                                key = keys[i];
                                this[key] = attributesToCopy[key];
                            }
                        } else {
                            this.$attr = {};
                        }
                        this.$$element = element;
                    }
                    Attributes.prototype = {
                        $normalize: directiveNormalize,
                        $addClass: function(classVal) {
                            if (classVal && classVal.length > 0) {
                                $animate.addClass(this.$$element, classVal);
                            }
                        },
                        $removeClass: function(classVal) {
                            if (classVal && classVal.length > 0) {
                                $animate.removeClass(this.$$element, classVal);
                            }
                        },
                        $updateClass: function(newClasses, oldClasses) {
                            var toAdd = tokenDifference(newClasses, oldClasses);
                            if (toAdd && toAdd.length) {
                                $animate.addClass(this.$$element, toAdd);
                            }
                            var toRemove = tokenDifference(oldClasses, newClasses);
                            if (toRemove && toRemove.length) {
                                $animate.removeClass(this.$$element, toRemove);
                            }
                        },
                        $set: function(key, value, writeAttr, attrName) {
                            var node = this.$$element[0],
                                booleanKey = getBooleanAttrName(node, key),
                                aliasedKey = getAliasedAttrName(key),
                                observer = key,
                                nodeName;
                            if (booleanKey) {
                                this.$$element.prop(key, value);
                                attrName = booleanKey;
                            } else if (aliasedKey) {
                                this[aliasedKey] = value;
                                observer = aliasedKey;
                            }
                            this[key] = value;
                            if (attrName) {
                                this.$attr[key] = attrName;
                            } else {
                                attrName = this.$attr[key];
                                if (!attrName) {
                                    this.$attr[key] = attrName = snake_case(key, '-');
                                }
                            }
                            nodeName = nodeName_(this.$$element);
                            if ((nodeName === 'a' && (key === 'href' || key === 'xlinkHref')) ||
                                (nodeName === 'img' && key === 'src')) {
                                this[key] = value = $$sanitizeUri(value, key === 'src');
                            } else if (nodeName === 'img' && key === 'srcset') {
                                var result = "";
                                var trimmedSrcset = trim(value);
                                var srcPattern = /(\s+\d+x\s*,|\s+\d+w\s*,|\s+,|,\s+)/;
                                var pattern = /\s/.test(trimmedSrcset) ? srcPattern : /(,)/;
                                var rawUris = trimmedSrcset.split(pattern);
                                var nbrUrisWith2parts = Math.floor(rawUris.length / 2);
                                for (var i = 0; i < nbrUrisWith2parts; i++) {
                                    var innerIdx = i * 2;
                                    result += $$sanitizeUri(trim(rawUris[innerIdx]), true);
                                    result += (" " + trim(rawUris[innerIdx + 1]));
                                }
                                var lastTuple = trim(rawUris[i * 2]).split(/\s/);
                                result += $$sanitizeUri(trim(lastTuple[0]), true);
                                if (lastTuple.length === 2) {
                                    result += (" " + trim(lastTuple[1]));
                                }
                                this[key] = value = result;
                            }
                            if (writeAttr !== false) {
                                if (value === null || isUndefined(value)) {
                                    this.$$element.removeAttr(attrName);
                                } else {
                                    if (SIMPLE_ATTR_NAME.test(attrName)) {
                                        this.$$element.attr(attrName, value);
                                    } else {
                                        setSpecialAttr(this.$$element[0], attrName, value);
                                    }
                                }
                            }
                            var $$observers = this.$$observers;
                            $$observers && forEach($$observers[observer], function(fn) {
                                try {
                                    fn(value);
                                } catch (e) {
                                    $exceptionHandler(e);
                                }
                            });
                        },
                        $observe: function(key, fn) {
                            var attrs = this,
                                $$observers = (attrs.$$observers || (attrs.$$observers = createMap())),
                                listeners = ($$observers[key] || ($$observers[key] = []));
                            listeners.push(fn);
                            $rootScope.$evalAsync(function() {
                                if (!listeners.$$inter && attrs.hasOwnProperty(key) && !isUndefined(attrs[key])) {
                                    fn(attrs[key]);
                                }
                            });
                            return function() {
                                arrayRemove(listeners, fn);
                            };
                        }
                    };
    
                    function setSpecialAttr(element, attrName, value) {
                        specialAttrHolder.innerHTML = "<span " + attrName + ">";
                        var attributes = specialAttrHolder.firstChild.attributes;
                        var attribute = attributes[0];
                        attributes.removeNamedItem(attribute.name);
                        attribute.value = value;
                        element.attributes.setNamedItem(attribute);
                    }
    
                    function safeAddClass($element, className) {
                        try {
                            $element.addClass(className);
                        } catch (e) {}
                    }
                    var startSymbol = $interpolate.startSymbol(),
                        endSymbol = $interpolate.endSymbol(),
                        denormalizeTemplate = (startSymbol == '{{' && endSymbol == '}}') ?
                        identity :
                        function denormalizeTemplate(template) {
                            return template.replace(/\{\{/g, startSymbol).replace(/}}/g, endSymbol);
                        },
                        NG_ATTR_BINDING = /^ngAttr[A-Z]/;
                    var MULTI_ELEMENT_DIR_RE = /^(.+)Start$/;
                    compile.$$addBindingInfo = debugInfoEnabled ? function $$addBindingInfo($element, binding) {
                        var bindings = $element.data('$binding') || [];
                        if (isArray(binding)) {
                            bindings = bindings.concat(binding);
                        } else {
                            bindings.push(binding);
                        }
                        $element.data('$binding', bindings);
                    } : noop;
                    compile.$$addBindingClass = debugInfoEnabled ? function $$addBindingClass($element) {
                        safeAddClass($element, 'ng-binding');
                    } : noop;
                    compile.$$addScopeInfo = debugInfoEnabled ? function $$addScopeInfo($element, scope, isolated, noTemplate) {
                        var dataName = isolated ? (noTemplate ? '$isolateScopeNoTemplate' : '$isolateScope') : '$scope';
                        $element.data(dataName, scope);
                    } : noop;
                    compile.$$addScopeClass = debugInfoEnabled ? function $$addScopeClass($element, isolated) {
                        safeAddClass($element, isolated ? 'ng-isolate-scope' : 'ng-scope');
                    } : noop;
                    compile.$$createComment = function(directiveName, comment) {
                        var content = '';
                        if (debugInfoEnabled) {
                            content = ' ' + (directiveName || '') + ': ' + (comment || '') + ' ';
                        }
                        return document.createComment(content);
                    };
                    return compile;
    
                    function compile($compileNodes, transcludeFn, maxPriority, ignoreDirective,
                        previousCompileContext) {
                        if (!($compileNodes instanceof jqLite)) {
                            $compileNodes = jqLite($compileNodes);
                        }
                        var NOT_EMPTY = /\S+/;
                        for (var i = 0, len = $compileNodes.length; i < len; i++) {
                            var domNode = $compileNodes[i];
                            if (domNode.nodeType === NODE_TYPE_TEXT && domNode.nodeValue.match(NOT_EMPTY)) {
                                jqLiteWrapNode(domNode, $compileNodes[i] = document.createElement('span'));
                            }
                        }
                        var compositeLinkFn =
                            compileNodes($compileNodes, transcludeFn, $compileNodes,
                                maxPriority, ignoreDirective, previousCompileContext);
                        compile.$$addScopeClass($compileNodes);
                        var namespace = null;
                        return function publicLinkFn(scope, cloneConnectFn, options) {
                            assertArg(scope, 'scope');
                            if (previousCompileContext && previousCompileContext.needsNewScope) {
                                scope = scope.$parent.$new();
                            }
                            options = options || {};
                            var parentBoundTranscludeFn = options.parentBoundTranscludeFn,
                                transcludeControllers = options.transcludeControllers,
                                futureParentElement = options.futureParentElement;
                            if (parentBoundTranscludeFn && parentBoundTranscludeFn.$$boundTransclude) {
                                parentBoundTranscludeFn = parentBoundTranscludeFn.$$boundTransclude;
                            }
                            if (!namespace) {
                                namespace = detectNamespaceForChildElements(futureParentElement);
                            }
                            var $linkNode;
                            if (namespace !== 'html') {
                                $linkNode = jqLite(
                                    wrapTemplate(namespace, jqLite('<div>').append($compileNodes).html())
                                );
                            } else if (cloneConnectFn) {
                                $linkNode = JQLitePrototype.clone.call($compileNodes);
                            } else {
                                $linkNode = $compileNodes;
                            }
                            if (transcludeControllers) {
                                for (var controllerName in transcludeControllers) {
                                    $linkNode.data('$' + controllerName + 'Controller', transcludeControllers[controllerName].instance);
                                }
                            }
                            compile.$$addScopeInfo($linkNode, scope);
                            if (cloneConnectFn) cloneConnectFn($linkNode, scope);
                            if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn);
                            return $linkNode;
                        };
                    }
    
                    function detectNamespaceForChildElements(parentElement) {
                        var node = parentElement && parentElement[0];
                        if (!node) {
                            return 'html';
                        } else {
                            return nodeName_(node) !== 'foreignobject' && toString.call(node).match(/SVG/) ? 'svg' : 'html';
                        }
                    }
    
                    function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective,
                        previousCompileContext) {
                        var linkFns = [],
                            attrs, directives, nodeLinkFn, childNodes, childLinkFn, linkFnFound, nodeLinkFnFound;
                        for (var i = 0; i < nodeList.length; i++) {
                            attrs = new Attributes();
                            directives = collectDirectives(nodeList[i], [], attrs, i === 0 ? maxPriority : undefined,
                                ignoreDirective);
                            nodeLinkFn = (directives.length) ?
                                applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement,
                                    null, [], [], previousCompileContext) :
                                null;
                            if (nodeLinkFn && nodeLinkFn.scope) {
                                compile.$$addScopeClass(attrs.$$element);
                            }
                            childLinkFn = (nodeLinkFn && nodeLinkFn.terminal ||
                                    !(childNodes = nodeList[i].childNodes) ||
                                    !childNodes.length) ?
                                null :
                                compileNodes(childNodes,
                                    nodeLinkFn ? (
                                        (nodeLinkFn.transcludeOnThisElement || !nodeLinkFn.templateOnThisElement) &&
                                        nodeLinkFn.transclude) : transcludeFn);
                            if (nodeLinkFn || childLinkFn) {
                                linkFns.push(i, nodeLinkFn, childLinkFn);
                                linkFnFound = true;
                                nodeLinkFnFound = nodeLinkFnFound || nodeLinkFn;
                            }
                            previousCompileContext = null;
                        }
                        return linkFnFound ? compositeLinkFn : null;
    
                        function compositeLinkFn(scope, nodeList, $rootElement, parentBoundTranscludeFn) {
                            var nodeLinkFn, childLinkFn, node, childScope, i, ii, idx, childBoundTranscludeFn;
                            var stableNodeList;
                            if (nodeLinkFnFound) {
                                var nodeListLength = nodeList.length;
                                stableNodeList = new Array(nodeListLength);
                                for (i = 0; i < linkFns.length; i += 3) {
                                    idx = linkFns[i];
                                    stableNodeList[idx] = nodeList[idx];
                                }
                            } else {
                                stableNodeList = nodeList;
                            }
                            for (i = 0, ii = linkFns.length; i < ii;) {
                                node = stableNodeList[linkFns[i++]];
                                nodeLinkFn = linkFns[i++];
                                childLinkFn = linkFns[i++];
                                if (nodeLinkFn) {
                                    if (nodeLinkFn.scope) {
                                        childScope = scope.$new();
                                        compile.$$addScopeInfo(jqLite(node), childScope);
                                    } else {
                                        childScope = scope;
                                    }
                                    if (nodeLinkFn.transcludeOnThisElement) {
                                        childBoundTranscludeFn = createBoundTranscludeFn(
                                            scope, nodeLinkFn.transclude, parentBoundTranscludeFn);
                                    } else if (!nodeLinkFn.templateOnThisElement && parentBoundTranscludeFn) {
                                        childBoundTranscludeFn = parentBoundTranscludeFn;
                                    } else if (!parentBoundTranscludeFn && transcludeFn) {
                                        childBoundTranscludeFn = createBoundTranscludeFn(scope, transcludeFn);
                                    } else {
                                        childBoundTranscludeFn = null;
                                    }
                                    nodeLinkFn(childLinkFn, childScope, node, $rootElement, childBoundTranscludeFn);
                                } else if (childLinkFn) {
                                    childLinkFn(scope, node.childNodes, undefined, parentBoundTranscludeFn);
                                }
                            }
                        }
                    }
    
                    function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) {
                        function boundTranscludeFn(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) {
                            if (!transcludedScope) {
                                transcludedScope = scope.$new(false, containingScope);
                                transcludedScope.$$transcluded = true;
                            }
                            return transcludeFn(transcludedScope, cloneFn, {
                                parentBoundTranscludeFn: previousBoundTranscludeFn,
                                transcludeControllers: controllers,
                                futureParentElement: futureParentElement
                            });
                        }
                        var boundSlots = boundTranscludeFn.$$slots = createMap();
                        for (var slotName in transcludeFn.$$slots) {
                            if (transcludeFn.$$slots[slotName]) {
                                boundSlots[slotName] = createBoundTranscludeFn(scope, transcludeFn.$$slots[slotName], previousBoundTranscludeFn);
                            } else {
                                boundSlots[slotName] = null;
                            }
                        }
                        return boundTranscludeFn;
                    }
    
                    function collectDirectives(node, directives, attrs, maxPriority, ignoreDirective) {
                        var nodeType = node.nodeType,
                            attrsMap = attrs.$attr,
                            match,
                            className;
                        switch (nodeType) {
                            case NODE_TYPE_ELEMENT:
                                addDirective(directives,
                                    directiveNormalize(nodeName_(node)), 'E', maxPriority, ignoreDirective);
                                for (var attr, name, nName, ngAttrName, value, isNgAttr, nAttrs = node.attributes,
                                        j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) {
                                    var attrStartName = false;
                                    var attrEndName = false;
                                    attr = nAttrs[j];
                                    name = attr.name;
                                    value = trim(attr.value);
                                    ngAttrName = directiveNormalize(name);
                                    if (isNgAttr = NG_ATTR_BINDING.test(ngAttrName)) {
                                        name = name.replace(PREFIX_REGEXP, '')
                                            .substr(8).replace(/_(.)/g, function(match, letter) {
                                                return letter.toUpperCase();
                                            });
                                    }
                                    var multiElementMatch = ngAttrName.match(MULTI_ELEMENT_DIR_RE);
                                    if (multiElementMatch && directiveIsMultiElement(multiElementMatch[1])) {
                                        attrStartName = name;
                                        attrEndName = name.substr(0, name.length - 5) + 'end';
                                        name = name.substr(0, name.length - 6);
                                    }
                                    nName = directiveNormalize(name.toLowerCase());
                                    attrsMap[nName] = name;
                                    if (isNgAttr || !attrs.hasOwnProperty(nName)) {
                                        attrs[nName] = value;
                                        if (getBooleanAttrName(node, nName)) {
                                            attrs[nName] = true;
                                        }
                                    }
                                    addAttrInterpolateDirective(node, directives, value, nName, isNgAttr);
                                    addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName,
                                        attrEndName);
                                }
                                className = node.className;
                                if (isObject(className)) {
                                    className = className.animVal;
                                }
                                if (isString(className) && className !== '') {
                                    while (match = CLASS_DIRECTIVE_REGEXP.exec(className)) {
                                        nName = directiveNormalize(match[2]);
                                        if (addDirective(directives, nName, 'C', maxPriority, ignoreDirective)) {
                                            attrs[nName] = trim(match[3]);
                                        }
                                        className = className.substr(match.index + match[0].length);
                                    }
                                }
                                break;
                            case NODE_TYPE_TEXT:
                                if (msie === 11) {
                                    while (node.parentNode && node.nextSibling && node.nextSibling.nodeType === NODE_TYPE_TEXT) {
                                        node.nodeValue = node.nodeValue + node.nextSibling.nodeValue;
                                        node.parentNode.removeChild(node.nextSibling);
                                    }
                                }
                                addTextInterpolateDirective(directives, node.nodeValue);
                                break;
                            case NODE_TYPE_COMMENT:
                                try {
                                    match = COMMENT_DIRECTIVE_REGEXP.exec(node.nodeValue);
                                    if (match) {
                                        nName = directiveNormalize(match[1]);
                                        if (addDirective(directives, nName, 'M', maxPriority, ignoreDirective)) {
                                            attrs[nName] = trim(match[2]);
                                        }
                                    }
                                } catch (e) {}
                                break;
                        }
                        directives.sort(byPriority);
                        return directives;
                    }
    
                    function groupScan(node, attrStart, attrEnd) {
                        var nodes = [];
                        var depth = 0;
                        if (attrStart && node.hasAttribute && node.hasAttribute(attrStart)) {
                            do {
                                if (!node) {
                                    throw $compileMinErr('uterdir',
                                        "Unterminated attribute, found '{0}' but no matching '{1}' found.",
                                        attrStart, attrEnd);
                                }
                                if (node.nodeType == NODE_TYPE_ELEMENT) {
                                    if (node.hasAttribute(attrStart)) depth++;
                                    if (node.hasAttribute(attrEnd)) depth--;
                                }
                                nodes.push(node);
                                node = node.nextSibling;
                            } while (depth > 0);
                        } else {
                            nodes.push(node);
                        }
                        return jqLite(nodes);
                    }
    
                    function groupElementsLinkFnWrapper(linkFn, attrStart, attrEnd) {
                        return function groupedElementsLink(scope, element, attrs, controllers, transcludeFn) {
                            element = groupScan(element[0], attrStart, attrEnd);
                            return linkFn(scope, element, attrs, controllers, transcludeFn);
                        };
                    }
    
                    function compilationGenerator(eager, $compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext) {
                        var compiled;
                        if (eager) {
                            return compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);
                        }
                        return function lazyCompilation() {
                            if (!compiled) {
                                compiled = compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);
                                $compileNodes = transcludeFn = previousCompileContext = null;
                            }
                            return compiled.apply(this, arguments);
                        };
                    }
    
                    function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn,
                        jqCollection, originalReplaceDirective, preLinkFns, postLinkFns,
                        previousCompileContext) {
                        previousCompileContext = previousCompileContext || {};
                        var terminalPriority = -Number.MAX_VALUE,
                            newScopeDirective = previousCompileContext.newScopeDirective,
                            controllerDirectives = previousCompileContext.controllerDirectives,
                            newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective,
                            templateDirective = previousCompileContext.templateDirective,
                            nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective,
                            hasTranscludeDirective = false,
                            hasTemplate = false,
                            hasElementTranscludeDirective = previousCompileContext.hasElementTranscludeDirective,
                            $compileNode = templateAttrs.$$element = jqLite(compileNode),
                            directive,
                            directiveName,
                            $template,
                            replaceDirective = originalReplaceDirective,
                            childTranscludeFn = transcludeFn,
                            linkFn,
                            didScanForMultipleTransclusion = false,
                            mightHaveMultipleTransclusionError = false,
                            directiveValue;
                        for (var i = 0, ii = directives.length; i < ii; i++) {
                            directive = directives[i];
                            var attrStart = directive.$$start;
                            var attrEnd = directive.$$end;
                            if (attrStart) {
                                $compileNode = groupScan(compileNode, attrStart, attrEnd);
                            }
                            $template = undefined;
                            if (terminalPriority > directive.priority) {
                                break;
                            }
                            if (directiveValue = directive.scope) {
                                if (!directive.templateUrl) {
                                    if (isObject(directiveValue)) {
                                        assertNoDuplicate('new/isolated scope', newIsolateScopeDirective || newScopeDirective,
                                            directive, $compileNode);
                                        newIsolateScopeDirective = directive;
                                    } else {
                                        assertNoDuplicate('new/isolated scope', newIsolateScopeDirective, directive,
                                            $compileNode);
                                    }
                                }
                                newScopeDirective = newScopeDirective || directive;
                            }
                            directiveName = directive.name;
                            if (!didScanForMultipleTransclusion && ((directive.replace && (directive.templateUrl || directive.template)) ||
                                    (directive.transclude && !directive.$$tlb))) {
                                var candidateDirective;
                                for (var scanningIndex = i + 1; candidateDirective = directives[scanningIndex++];) {
                                    if ((candidateDirective.transclude && !candidateDirective.$$tlb) ||
                                        (candidateDirective.replace && (candidateDirective.templateUrl || candidateDirective.template))) {
                                        mightHaveMultipleTransclusionError = true;
                                        break;
                                    }
                                }
                                didScanForMultipleTransclusion = true;
                            }
                            if (!directive.templateUrl && directive.controller) {
                                directiveValue = directive.controller;
                                controllerDirectives = controllerDirectives || createMap();
                                assertNoDuplicate("'" + directiveName + "' controller",
                                    controllerDirectives[directiveName], directive, $compileNode);
                                controllerDirectives[directiveName] = directive;
                            }
                            if (directiveValue = directive.transclude) {
                                hasTranscludeDirective = true;
                                if (!directive.$$tlb) {
                                    assertNoDuplicate('transclusion', nonTlbTranscludeDirective, directive, $compileNode);
                                    nonTlbTranscludeDirective = directive;
                                }
                                if (directiveValue == 'element') {
                                    hasElementTranscludeDirective = true;
                                    terminalPriority = directive.priority;
                                    $template = $compileNode;
                                    $compileNode = templateAttrs.$$element =
                                        jqLite(compile.$$createComment(directiveName, templateAttrs[directiveName]));
                                    compileNode = $compileNode[0];
                                    replaceWith(jqCollection, sliceArgs($template), compileNode);
                                    $template[0].$$parentNode = $template[0].parentNode;
                                    childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn, terminalPriority,
                                        replaceDirective && replaceDirective.name, {
                                            nonTlbTranscludeDirective: nonTlbTranscludeDirective
                                        });
                                } else {
                                    var slots = createMap();
                                    $template = jqLite(jqLiteClone(compileNode)).contents();
                                    if (isObject(directiveValue)) {
                                        $template = [];
                                        var slotMap = createMap();
                                        var filledSlots = createMap();
                                        forEach(directiveValue, function(elementSelector, slotName) {
                                            var optional = (elementSelector.charAt(0) === '?');
                                            elementSelector = optional ? elementSelector.substring(1) : elementSelector;
                                            slotMap[elementSelector] = slotName;
                                            slots[slotName] = null;
                                            filledSlots[slotName] = optional;
                                        });
                                        forEach($compileNode.contents(), function(node) {
                                            var slotName = slotMap[directiveNormalize(nodeName_(node))];
                                            if (slotName) {
                                                filledSlots[slotName] = true;
                                                slots[slotName] = slots[slotName] || [];
                                                slots[slotName].push(node);
                                            } else {
                                                $template.push(node);
                                            }
                                        });
                                        forEach(filledSlots, function(filled, slotName) {
                                            if (!filled) {
                                                throw $compileMinErr('reqslot', 'Required transclusion slot `{0}` was not filled.', slotName);
                                            }
                                        });
                                        for (var slotName in slots) {
                                            if (slots[slotName]) {
                                                slots[slotName] = compilationGenerator(mightHaveMultipleTransclusionError, slots[slotName], transcludeFn);
                                            }
                                        }
                                    }
                                    $compileNode.empty();
                                    childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn, undefined,
                                        undefined, {
                                            needsNewScope: directive.$$isolateScope || directive.$$newScope
                                        });
                                    childTranscludeFn.$$slots = slots;
                                }
                            }
                            if (directive.template) {
                                hasTemplate = true;
                                assertNoDuplicate('template', templateDirective, directive, $compileNode);
                                templateDirective = directive;
                                directiveValue = (isFunction(directive.template)) ?
                                    directive.template($compileNode, templateAttrs) :
                                    directive.template;
                                directiveValue = denormalizeTemplate(directiveValue);
                                if (directive.replace) {
                                    replaceDirective = directive;
                                    if (jqLiteIsTextNode(directiveValue)) {
                                        $template = [];
                                    } else {
                                        $template = removeComments(wrapTemplate(directive.templateNamespace, trim(directiveValue)));
                                    }
                                    compileNode = $template[0];
                                    if ($template.length != 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) {
                                        throw $compileMinErr('tplrt',
                                            "Template for directive '{0}' must have exactly one root element. {1}",
                                            directiveName, '');
                                    }
                                    replaceWith(jqCollection, $compileNode, compileNode);
                                    var newTemplateAttrs = {
                                        $attr: {}
                                    };
                                    var templateDirectives = collectDirectives(compileNode, [], newTemplateAttrs);
                                    var unprocessedDirectives = directives.splice(i + 1, directives.length - (i + 1));
                                    if (newIsolateScopeDirective || newScopeDirective) {
                                        markDirectiveScope(templateDirectives, newIsolateScopeDirective, newScopeDirective);
                                    }
                                    directives = directives.concat(templateDirectives).concat(unprocessedDirectives);
                                    mergeTemplateAttributes(templateAttrs, newTemplateAttrs);
                                    ii = directives.length;
                                } else {
                                    $compileNode.html(directiveValue);
                                }
                            }
                            if (directive.templateUrl) {
                                hasTemplate = true;
                                assertNoDuplicate('template', templateDirective, directive, $compileNode);
                                templateDirective = directive;
                                if (directive.replace) {
                                    replaceDirective = directive;
                                }
                                nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode,
                                    templateAttrs, jqCollection, hasTranscludeDirective && childTranscludeFn, preLinkFns, postLinkFns, {
                                        controllerDirectives: controllerDirectives,
                                        newScopeDirective: (newScopeDirective !== directive) && newScopeDirective,
                                        newIsolateScopeDirective: newIsolateScopeDirective,
                                        templateDirective: templateDirective,
                                        nonTlbTranscludeDirective: nonTlbTranscludeDirective
                                    });
                                ii = directives.length;
                            } else if (directive.compile) {
                                try {
                                    linkFn = directive.compile($compileNode, templateAttrs, childTranscludeFn);
                                    if (isFunction(linkFn)) {
                                        addLinkFns(null, linkFn, attrStart, attrEnd);
                                    } else if (linkFn) {
                                        addLinkFns(linkFn.pre, linkFn.post, attrStart, attrEnd);
                                    }
                                } catch (e) {
                                    $exceptionHandler(e, startingTag($compileNode));
                                }
                            }
                            if (directive.terminal) {
                                nodeLinkFn.terminal = true;
                                terminalPriority = Math.max(terminalPriority, directive.priority);
                            }
                        }
                        nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true;
                        nodeLinkFn.transcludeOnThisElement = hasTranscludeDirective;
                        nodeLinkFn.templateOnThisElement = hasTemplate;
                        nodeLinkFn.transclude = childTranscludeFn;
                        previousCompileContext.hasElementTranscludeDirective = hasElementTranscludeDirective;
                        return nodeLinkFn;
    
                        function addLinkFns(pre, post, attrStart, attrEnd) {
                            if (pre) {
                                if (attrStart) pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd);
                                pre.require = directive.require;
                                pre.directiveName = directiveName;
                                if (newIsolateScopeDirective === directive || directive.$$isolateScope) {
                                    pre = cloneAndAnnotateFn(pre, {
                                        isolateScope: true
                                    });
                                }
                                preLinkFns.push(pre);
                            }
                            if (post) {
                                if (attrStart) post = groupElementsLinkFnWrapper(post, attrStart, attrEnd);
                                post.require = directive.require;
                                post.directiveName = directiveName;
                                if (newIsolateScopeDirective === directive || directive.$$isolateScope) {
                                    post = cloneAndAnnotateFn(post, {
                                        isolateScope: true
                                    });
                                }
                                postLinkFns.push(post);
                            }
                        }
    
                        function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {
                            var i, ii, linkFn, isolateScope, controllerScope, elementControllers, transcludeFn, $element,
                                attrs, removeScopeBindingWatches, removeControllerBindingWatches;
                            if (compileNode === linkNode) {
                                attrs = templateAttrs;
                                $element = templateAttrs.$$element;
                            } else {
                                $element = jqLite(linkNode);
                                attrs = new Attributes($element, templateAttrs);
                            }
                            controllerScope = scope;
                            if (newIsolateScopeDirective) {
                                isolateScope = scope.$new(true);
                            } else if (newScopeDirective) {
                                controllerScope = scope.$parent;
                            }
                            if (boundTranscludeFn) {
                                transcludeFn = controllersBoundTransclude;
                                transcludeFn.$$boundTransclude = boundTranscludeFn;
                                transcludeFn.isSlotFilled = function(slotName) {
                                    return !!boundTranscludeFn.$$slots[slotName];
                                };
                            }
                            if (controllerDirectives) {
                                elementControllers = setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope, newIsolateScopeDirective);
                            }
                            if (newIsolateScopeDirective) {
                                compile.$$addScopeInfo($element, isolateScope, true, !(templateDirective && (templateDirective === newIsolateScopeDirective ||
                                    templateDirective === newIsolateScopeDirective.$$originalDirective)));
                                compile.$$addScopeClass($element, true);
                                isolateScope.$$isolateBindings =
                                    newIsolateScopeDirective.$$isolateBindings;
                                removeScopeBindingWatches = initializeDirectiveBindings(scope, attrs, isolateScope,
                                    isolateScope.$$isolateBindings,
                                    newIsolateScopeDirective);
                                if (removeScopeBindingWatches) {
                                    isolateScope.$on('$destroy', removeScopeBindingWatches);
                                }
                            }
                            for (var name in elementControllers) {
                                var controllerDirective = controllerDirectives[name];
                                var controller = elementControllers[name];
                                var bindings = controllerDirective.$$bindings.bindToController;
                                if (controller.identifier && bindings) {
                                    removeControllerBindingWatches =
                                        initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);
                                }
                                var controllerResult = controller();
                                if (controllerResult !== controller.instance) {
                                    controller.instance = controllerResult;
                                    $element.data('$' + controllerDirective.name + 'Controller', controllerResult);
                                    removeControllerBindingWatches && removeControllerBindingWatches();
                                    removeControllerBindingWatches =
                                        initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);
                                }
                            }
                            forEach(controllerDirectives, function(controllerDirective, name) {
                                var require = controllerDirective.require;
                                if (controllerDirective.bindToController && !isArray(require) && isObject(require)) {
                                    extend(elementControllers[name].instance, getControllers(name, require, $element, elementControllers));
                                }
                            });
                            forEach(elementControllers, function(controller) {
                                var controllerInstance = controller.instance;
                                if (isFunction(controllerInstance.$onInit)) {
                                    controllerInstance.$onInit();
                                }
                                if (isFunction(controllerInstance.$onDestroy)) {
                                    controllerScope.$on('$destroy', function callOnDestroyHook() {
                                        controllerInstance.$onDestroy();
                                    });
                                }
                            });
                            for (i = 0, ii = preLinkFns.length; i < ii; i++) {
                                linkFn = preLinkFns[i];
                                invokeLinkFn(linkFn,
                                    linkFn.isolateScope ? isolateScope : scope,
                                    $element,
                                    attrs,
                                    linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers),
                                    transcludeFn
                                );
                            }
                            var scopeToChild = scope;
                            if (newIsolateScopeDirective && (newIsolateScopeDirective.template || newIsolateScopeDirective.templateUrl === null)) {
                                scopeToChild = isolateScope;
                            }
                            childLinkFn && childLinkFn(scopeToChild, linkNode.childNodes, undefined, boundTranscludeFn);
                            for (i = postLinkFns.length - 1; i >= 0; i--) {
                                linkFn = postLinkFns[i];
                                invokeLinkFn(linkFn,
                                    linkFn.isolateScope ? isolateScope : scope,
                                    $element,
                                    attrs,
                                    linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers),
                                    transcludeFn
                                );
                            }
                            forEach(elementControllers, function(controller) {
                                var controllerInstance = controller.instance;
                                if (isFunction(controllerInstance.$postLink)) {
                                    controllerInstance.$postLink();
                                }
                            });
    
                            function controllersBoundTransclude(scope, cloneAttachFn, futureParentElement, slotName) {
                                var transcludeControllers;
                                if (!isScope(scope)) {
                                    slotName = futureParentElement;
                                    futureParentElement = cloneAttachFn;
                                    cloneAttachFn = scope;
                                    scope = undefined;
                                }
                                if (hasElementTranscludeDirective) {
                                    transcludeControllers = elementControllers;
                                }
                                if (!futureParentElement) {
                                    futureParentElement = hasElementTranscludeDirective ? $element.parent() : $element;
                                }
                                if (slotName) {
                                    var slotTranscludeFn = boundTranscludeFn.$$slots[slotName];
                                    if (slotTranscludeFn) {
                                        return slotTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);
                                    } else if (isUndefined(slotTranscludeFn)) {
                                        throw $compileMinErr('noslot',
                                            'No parent directive that requires a transclusion with slot name "{0}". ' +
                                            'Element: {1}',
                                            slotName, startingTag($element));
                                    }
                                } else {
                                    return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);
                                }
                            }
                        }
                    }
    
                    function getControllers(directiveName, require, $element, elementControllers) {
                        var value;
                        if (isString(require)) {
                            var match = require.match(REQUIRE_PREFIX_REGEXP);
                            var name = require.substring(match[0].length);
                            var inheritType = match[1] || match[3];
                            var optional = match[2] === '?';
                            if (inheritType === '^^') {
                                $element = $element.parent();
                            } else {
                                value = elementControllers && elementControllers[name];
                                value = value && value.instance;
                            }
                            if (!value) {
                                var dataName = '$' + name + 'Controller';
                                value = inheritType ? $element.inheritedData(dataName) : $element.data(dataName);
                            }
                            if (!value && !optional) {
                                throw $compileMinErr('ctreq',
                                    "Controller '{0}', required by directive '{1}', can't be found!",
                                    name, directiveName);
                            }
                        } else if (isArray(require)) {
                            value = [];
                            for (var i = 0, ii = require.length; i < ii; i++) {
                                value[i] = getControllers(directiveName, require[i], $element, elementControllers);
                            }
                        } else if (isObject(require)) {
                            value = {};
                            forEach(require, function(controller, property) {
                                value[property] = getControllers(directiveName, controller, $element, elementControllers);
                            });
                        }
                        return value || null;
                    }
    
                    function setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope, newIsolateScopeDirective) {
                        var elementControllers = createMap();
                        for (var controllerKey in controllerDirectives) {
                            var directive = controllerDirectives[controllerKey];
                            var locals = {
                                $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
                                $element: $element,
                                $attrs: attrs,
                                $transclude: transcludeFn
                            };
                            var controller = directive.controller;
                            if (controller == '@') {
                                controller = attrs[directive.name];
                            }
                            var controllerInstance = $controller(controller, locals, true, directive.controllerAs);
                            elementControllers[directive.name] = controllerInstance;
                            $element.data('$' + directive.name + 'Controller', controllerInstance.instance);
                        }
                        return elementControllers;
                    }
    
                    function markDirectiveScope(directives, isolateScope, newScope) {
                        for (var j = 0, jj = directives.length; j < jj; j++) {
                            directives[j] = inherit(directives[j], {
                                $$isolateScope: isolateScope,
                                $$newScope: newScope
                            });
                        }
                    }
    
                    function addDirective(tDirectives, name, location, maxPriority, ignoreDirective, startAttrName,
                        endAttrName) {
                        if (name === ignoreDirective) return null;
                        var match = null;
                        if (hasDirectives.hasOwnProperty(name)) {
                            for (var directive, directives = $injector.get(name + Suffix),
                                    i = 0, ii = directives.length; i < ii; i++) {
                                try {
                                    directive = directives[i];
                                    if ((isUndefined(maxPriority) || maxPriority > directive.priority) &&
                                        directive.restrict.indexOf(location) != -1) {
                                        if (startAttrName) {
                                            directive = inherit(directive, {
                                                $$start: startAttrName,
                                                $$end: endAttrName
                                            });
                                        }
                                        if (!directive.$$bindings) {
                                            var bindings = directive.$$bindings =
                                                parseDirectiveBindings(directive, directive.name);
                                            if (isObject(bindings.isolateScope)) {
                                                directive.$$isolateBindings = bindings.isolateScope;
                                            }
                                        }
                                        tDirectives.push(directive);
                                        match = directive;
                                    }
                                } catch (e) {
                                    $exceptionHandler(e);
                                }
                            }
                        }
                        return match;
                    }
    
                    function directiveIsMultiElement(name) {
                        if (hasDirectives.hasOwnProperty(name)) {
                            for (var directive, directives = $injector.get(name + Suffix),
                                    i = 0, ii = directives.length; i < ii; i++) {
                                directive = directives[i];
                                if (directive.multiElement) {
                                    return true;
                                }
                            }
                        }
                        return false;
                    }
    
                    function mergeTemplateAttributes(dst, src) {
                        var srcAttr = src.$attr,
                            dstAttr = dst.$attr,
                            $element = dst.$$element;
                        forEach(dst, function(value, key) {
                            if (key.charAt(0) != '$') {
                                if (src[key] && src[key] !== value) {
                                    value += (key === 'style' ? ';' : ' ') + src[key];
                                }
                                dst.$set(key, value, true, srcAttr[key]);
                            }
                        });
                        forEach(src, function(value, key) {
                            if (key == 'class') {
                                safeAddClass($element, value);
                                dst['class'] = (dst['class'] ? dst['class'] + ' ' : '') + value;
                            } else if (key == 'style') {
                                $element.attr('style', $element.attr('style') + ';' + value);
                                dst['style'] = (dst['style'] ? dst['style'] + ';' : '') + value;
                            } else if (key.charAt(0) != '$' && !dst.hasOwnProperty(key)) {
                                dst[key] = value;
                                dstAttr[key] = srcAttr[key];
                            }
                        });
                    }
    
                    function compileTemplateUrl(directives, $compileNode, tAttrs,
                        $rootElement, childTranscludeFn, preLinkFns, postLinkFns, previousCompileContext) {
                        var linkQueue = [],
                            afterTemplateNodeLinkFn,
                            afterTemplateChildLinkFn,
                            beforeTemplateCompileNode = $compileNode[0],
                            origAsyncDirective = directives.shift(),
                            derivedSyncDirective = inherit(origAsyncDirective, {
                                templateUrl: null,
                                transclude: null,
                                replace: null,
                                $$originalDirective: origAsyncDirective
                            }),
                            templateUrl = (isFunction(origAsyncDirective.templateUrl)) ?
                            origAsyncDirective.templateUrl($compileNode, tAttrs) :
                            origAsyncDirective.templateUrl,
                            templateNamespace = origAsyncDirective.templateNamespace;
                        $compileNode.empty();
                        $templateRequest(templateUrl)
                            .then(function(content) {
                                var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn;
                                content = denormalizeTemplate(content);
                                if (origAsyncDirective.replace) {
                                    if (jqLiteIsTextNode(content)) {
                                        $template = [];
                                    } else {
                                        $template = removeComments(wrapTemplate(templateNamespace, trim(content)));
                                    }
                                    compileNode = $template[0];
                                    if ($template.length != 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) {
                                        throw $compileMinErr('tplrt',
                                            "Template for directive '{0}' must have exactly one root element. {1}",
                                            origAsyncDirective.name, templateUrl);
                                    }
                                    tempTemplateAttrs = {
                                        $attr: {}
                                    };
                                    replaceWith($rootElement, $compileNode, compileNode);
                                    var templateDirectives = collectDirectives(compileNode, [], tempTemplateAttrs);
                                    if (isObject(origAsyncDirective.scope)) {
                                        markDirectiveScope(templateDirectives, true);
                                    }
                                    directives = templateDirectives.concat(directives);
                                    mergeTemplateAttributes(tAttrs, tempTemplateAttrs);
                                } else {
                                    compileNode = beforeTemplateCompileNode;
                                    $compileNode.html(content);
                                }
                                directives.unshift(derivedSyncDirective);
                                afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs,
                                    childTranscludeFn, $compileNode, origAsyncDirective, preLinkFns, postLinkFns,
                                    previousCompileContext);
                                forEach($rootElement, function(node, i) {
                                    if (node == compileNode) {
                                        $rootElement[i] = $compileNode[0];
                                    }
                                });
                                afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn);
                                while (linkQueue.length) {
                                    var scope = linkQueue.shift(),
                                        beforeTemplateLinkNode = linkQueue.shift(),
                                        linkRootElement = linkQueue.shift(),
                                        boundTranscludeFn = linkQueue.shift(),
                                        linkNode = $compileNode[0];
                                    if (scope.$$destroyed) continue;
                                    if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {
                                        var oldClasses = beforeTemplateLinkNode.className;
                                        if (!(previousCompileContext.hasElementTranscludeDirective &&
                                                origAsyncDirective.replace)) {
                                            linkNode = jqLiteClone(compileNode);
                                        }
                                        replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);
                                        safeAddClass(jqLite(linkNode), oldClasses);
                                    }
                                    if (afterTemplateNodeLinkFn.transcludeOnThisElement) {
                                        childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);
                                    } else {
                                        childBoundTranscludeFn = boundTranscludeFn;
                                    }
                                    afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement,
                                        childBoundTranscludeFn);
                                }
                                linkQueue = null;
                            });
                        return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, boundTranscludeFn) {
                            var childBoundTranscludeFn = boundTranscludeFn;
                            if (scope.$$destroyed) return;
                            if (linkQueue) {
                                linkQueue.push(scope,
                                    node,
                                    rootElement,
                                    childBoundTranscludeFn);
                            } else {
                                if (afterTemplateNodeLinkFn.transcludeOnThisElement) {
                                    childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);
                                }
                                afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, childBoundTranscludeFn);
                            }
                        };
                    }
    
                    function byPriority(a, b) {
                        var diff = b.priority - a.priority;
                        if (diff !== 0) return diff;
                        if (a.name !== b.name) return (a.name < b.name) ? -1 : 1;
                        return a.index - b.index;
                    }
    
                    function assertNoDuplicate(what, previousDirective, directive, element) {
                        function wrapModuleNameIfDefined(moduleName) {
                            return moduleName ?
                                (' (module: ' + moduleName + ')') :
                                '';
                        }
                        if (previousDirective) {
                            throw $compileMinErr('multidir', 'Multiple directives [{0}{1}, {2}{3}] asking for {4} on: {5}',
                                previousDirective.name, wrapModuleNameIfDefined(previousDirective.$$moduleName),
                                directive.name, wrapModuleNameIfDefined(directive.$$moduleName), what, startingTag(element));
                        }
                    }
    
                    function addTextInterpolateDirective(directives, text) {
                        var interpolateFn = $interpolate(text, true);
                        if (interpolateFn) {
                            directives.push({
                                priority: 0,
                                compile: function textInterpolateCompileFn(templateNode) {
                                    var templateNodeParent = templateNode.parent(),
                                        hasCompileParent = !!templateNodeParent.length;
                                    if (hasCompileParent) compile.$$addBindingClass(templateNodeParent);
                                    return function textInterpolateLinkFn(scope, node) {
                                        var parent = node.parent();
                                        if (!hasCompileParent) compile.$$addBindingClass(parent);
                                        compile.$$addBindingInfo(parent, interpolateFn.expressions);
                                        scope.$watch(interpolateFn, function interpolateFnWatchAction(value) {
                                            node[0].nodeValue = value;
                                        });
                                    };
                                }
                            });
                        }
                    }
    
                    function wrapTemplate(type, template) {
                        type = lowercase(type || 'html');
                        switch (type) {
                            case 'svg':
                            case 'math':
                                var wrapper = document.createElement('div');
                                wrapper.innerHTML = '<' + type + '>' + template + '</' + type + '>';
                                return wrapper.childNodes[0].childNodes;
                            default:
                                return template;
                        }
                    }
    
                    function getTrustedContext(node, attrNormalizedName) {
                        if (attrNormalizedName == "srcdoc") {
                            return $sce.HTML;
                        }
                        var tag = nodeName_(node);
                        if (attrNormalizedName == "xlinkHref" ||
                            (tag == "form" && attrNormalizedName == "action") ||
                            (tag != "img" && (attrNormalizedName == "src" ||
                                attrNormalizedName == "ngSrc"))) {
                            return $sce.RESOURCE_URL;
                        }
                    }
    
                    function addAttrInterpolateDirective(node, directives, value, name, allOrNothing) {
                        var trustedContext = getTrustedContext(node, name);
                        allOrNothing = ALL_OR_NOTHING_ATTRS[name] || allOrNothing;
                        var interpolateFn = $interpolate(value, true, trustedContext, allOrNothing);
                        if (!interpolateFn) return;
                        if (name === "multiple" && nodeName_(node) === "select") {
                            throw $compileMinErr("selmulti",
                                "Binding to the 'multiple' attribute is not supported. Element: {0}",
                                startingTag(node));
                        }
                        directives.push({
                            priority: 100,
                            compile: function() {
                                return {
                                    pre: function attrInterpolatePreLinkFn(scope, element, attr) {
                                        var $$observers = (attr.$$observers || (attr.$$observers = createMap()));
                                        if (EVENT_HANDLER_ATTR_REGEXP.test(name)) {
                                            throw $compileMinErr('nodomevents',
                                                "Interpolations for HTML DOM event attributes are disallowed.  Please use the " +
                                                "ng- versions (such as ng-click instead of onclick) instead.");
                                        }
                                        var newValue = attr[name];
                                        if (newValue !== value) {
                                            interpolateFn = newValue && $interpolate(newValue, true, trustedContext, allOrNothing);
                                            value = newValue;
                                        }
                                        if (!interpolateFn) return;
                                        attr[name] = interpolateFn(scope);
                                        ($$observers[name] || ($$observers[name] = [])).$$inter = true;
                                        (attr.$$observers && attr.$$observers[name].$$scope || scope).
                                        $watch(interpolateFn, function interpolateFnWatchAction(newValue, oldValue) {
                                            if (name === 'class' && newValue != oldValue) {
                                                attr.$updateClass(newValue, oldValue);
                                            } else {
                                                attr.$set(name, newValue);
                                            }
                                        });
                                    }
                                };
                            }
                        });
                    }
    
                    function replaceWith($rootElement, elementsToRemove, newNode) {
                        var firstElementToRemove = elementsToRemove[0],
                            removeCount = elementsToRemove.length,
                            parent = firstElementToRemove.parentNode,
                            i, ii;
                        if ($rootElement) {
                            for (i = 0, ii = $rootElement.length; i < ii; i++) {
                                if ($rootElement[i] == firstElementToRemove) {
                                    $rootElement[i++] = newNode;
                                    for (var j = i, j2 = j + removeCount - 1,
                                            jj = $rootElement.length; j < jj; j++, j2++) {
                                        if (j2 < jj) {
                                            $rootElement[j] = $rootElement[j2];
                                        } else {
                                            delete $rootElement[j];
                                        }
                                    }
                                    $rootElement.length -= removeCount - 1;
                                    if ($rootElement.context === firstElementToRemove) {
                                        $rootElement.context = newNode;
                                    }
                                    break;
                                }
                            }
                        }
                        if (parent) {
                            parent.replaceChild(newNode, firstElementToRemove);
                        }
                        var fragment = document.createDocumentFragment();
                        for (i = 0; i < removeCount; i++) {
                            fragment.appendChild(elementsToRemove[i]);
                        }
                        if (jqLite.hasData(firstElementToRemove)) {
                            jqLite.data(newNode, jqLite.data(firstElementToRemove));
                            jqLite(firstElementToRemove).off('$destroy');
                        }
                        jqLite.cleanData(fragment.querySelectorAll('*'));
                        for (i = 1; i < removeCount; i++) {
                            delete elementsToRemove[i];
                        }
                        elementsToRemove[0] = newNode;
                        elementsToRemove.length = 1;
                    }
    
                    function cloneAndAnnotateFn(fn, annotation) {
                        return extend(function() {
                            return fn.apply(null, arguments);
                        }, fn, annotation);
                    }
    
                    function invokeLinkFn(linkFn, scope, $element, attrs, controllers, transcludeFn) {
                        try {
                            linkFn(scope, $element, attrs, controllers, transcludeFn);
                        } catch (e) {
                            $exceptionHandler(e, startingTag($element));
                        }
                    }
    
                    function initializeDirectiveBindings(scope, attrs, destination, bindings, directive) {
                        var removeWatchCollection = [];
                        var changes;
                        forEach(bindings, function initializeBinding(definition, scopeName) {
                            var attrName = definition.attrName,
                                optional = definition.optional,
                                mode = definition.mode,
                                lastValue,
                                parentGet, parentSet, compare, removeWatch;
                            switch (mode) {
                                case '@':
                                    if (!optional && !hasOwnProperty.call(attrs, attrName)) {
                                        destination[scopeName] = attrs[attrName] = void 0;
                                    }
                                    attrs.$observe(attrName, function(value) {
                                        if (isString(value)) {
                                            var oldValue = destination[scopeName];
                                            recordChanges(scopeName, value, oldValue);
                                            destination[scopeName] = value;
                                        }
                                    });
                                    attrs.$$observers[attrName].$$scope = scope;
                                    lastValue = attrs[attrName];
                                    if (isString(lastValue)) {
                                        destination[scopeName] = $interpolate(lastValue)(scope);
                                    } else if (isBoolean(lastValue)) {
                                        destination[scopeName] = lastValue;
                                    }
                                    break;
                                case '=':
                                    if (!hasOwnProperty.call(attrs, attrName)) {
                                        if (optional) break;
                                        attrs[attrName] = void 0;
                                    }
                                    if (optional && !attrs[attrName]) break;
                                    parentGet = $parse(attrs[attrName]);
                                    if (parentGet.literal) {
                                        compare = equals;
                                    } else {
                                        compare = function simpleCompare(a, b) {
                                            return a === b || (a !== a && b !== b);
                                        };
                                    }
                                    parentSet = parentGet.assign || function() {
                                        lastValue = destination[scopeName] = parentGet(scope);
                                        throw $compileMinErr('nonassign',
                                            "Expression '{0}' in attribute '{1}' used with directive '{2}' is non-assignable!",
                                            attrs[attrName], attrName, directive.name);
                                    };
                                    lastValue = destination[scopeName] = parentGet(scope);
                                    var parentValueWatch = function parentValueWatch(parentValue) {
                                        if (!compare(parentValue, destination[scopeName])) {
                                            if (!compare(parentValue, lastValue)) {
                                                destination[scopeName] = parentValue;
                                            } else {
                                                parentSet(scope, parentValue = destination[scopeName]);
                                            }
                                        }
                                        return lastValue = parentValue;
                                    };
                                    parentValueWatch.$stateful = true;
                                    if (definition.collection) {
                                        removeWatch = scope.$watchCollection(attrs[attrName], parentValueWatch);
                                    } else {
                                        removeWatch = scope.$watch($parse(attrs[attrName], parentValueWatch), null, parentGet.literal);
                                    }
                                    removeWatchCollection.push(removeWatch);
                                    break;
                                case '<':
                                    if (!hasOwnProperty.call(attrs, attrName)) {
                                        if (optional) break;
                                        attrs[attrName] = void 0;
                                    }
                                    if (optional && !attrs[attrName]) break;
                                    parentGet = $parse(attrs[attrName]);
                                    destination[scopeName] = parentGet(scope);
                                    removeWatch = scope.$watch(parentGet, function parentValueWatchAction(newParentValue) {
                                        var oldValue = destination[scopeName];
                                        recordChanges(scopeName, newParentValue, oldValue);
                                        destination[scopeName] = newParentValue;
                                    }, parentGet.literal);
                                    removeWatchCollection.push(removeWatch);
                                    break;
                                case '&':
                                    parentGet = attrs.hasOwnProperty(attrName) ? $parse(attrs[attrName]) : noop;
                                    if (parentGet === noop && optional) break;
                                    destination[scopeName] = function(locals) {
                                        return parentGet(scope, locals);
                                    };
                                    break;
                            }
                        });
    
                        function recordChanges(key, currentValue, previousValue) {
                            if (isFunction(destination.$onChanges) && currentValue !== previousValue) {
                                if (!onChangesQueue) {
                                    scope.$$postDigest(flushOnChangesQueue);
                                    onChangesQueue = [];
                                }
                                if (!changes) {
                                    changes = {};
                                    onChangesQueue.push(triggerOnChangesHook);
                                }
                                if (changes[key]) {
                                    previousValue = changes[key].previousValue;
                                }
                                changes[key] = {
                                    previousValue: previousValue,
                                    currentValue: currentValue
                                };
                            }
                        }
    
                        function triggerOnChangesHook() {
                            destination.$onChanges(changes);
                            changes = undefined;
                        }
                        return removeWatchCollection.length && function removeWatches() {
                            for (var i = 0, ii = removeWatchCollection.length; i < ii; ++i) {
                                removeWatchCollection[i]();
                            }
                        };
                    }
                }
            ];
        }
        var PREFIX_REGEXP = /^((?:x|data)[\:\-_])/i;
    
        function directiveNormalize(name) {
            return camelCase(name.replace(PREFIX_REGEXP, ''));
        }
    
        function nodesetLinkingFn(
            scope,
            nodeList,
            rootElement,
            boundTranscludeFn
        ) {}
    
        function directiveLinkingFn(
            nodesetLinkingFn,
            scope,
            node,
            rootElement,
            boundTranscludeFn
        ) {}
    
        function tokenDifference(str1, str2) {
            var values = '',
                tokens1 = str1.split(/\s+/),
                tokens2 = str2.split(/\s+/);
            outer:
                for (var i = 0; i < tokens1.length; i++) {
                    var token = tokens1[i];
                    for (var j = 0; j < tokens2.length; j++) {
                        if (token == tokens2[j]) continue outer;
                    }
                    values += (values.length > 0 ? ' ' : '') + token;
                }
            return values;
        }
    
        function removeComments(jqNodes) {
            jqNodes = jqLite(jqNodes);
            var i = jqNodes.length;
            if (i <= 1) {
                return jqNodes;
            }
            while (i--) {
                var node = jqNodes[i];
                if (node.nodeType === NODE_TYPE_COMMENT) {
                    splice.call(jqNodes, i, 1);
                }
            }
            return jqNodes;
        }
        var $controllerMinErr = minErr('$controller');
        var CNTRL_REG = /^(\S+)(\s+as\s+([\w$]+))?$/;
    
        function identifierForController(controller, ident) {
            if (ident && isString(ident)) return ident;
            if (isString(controller)) {
                var match = CNTRL_REG.exec(controller);
                if (match) return match[3];
            }
        }
    
        function $ControllerProvider() {
            var controllers = {},
                globals = false;
            this.has = function(name) {
                return controllers.hasOwnProperty(name);
            };
            this.register = function(name, constructor) {
                assertNotHasOwnProperty(name, 'controller');
                if (isObject(name)) {
                    extend(controllers, name);
                } else {
                    controllers[name] = constructor;
                }
            };
            this.allowGlobals = function() {
                globals = true;
            };
            this.$get = ['$injector', '$window', function($injector, $window) {
                return function $controller(expression, locals, later, ident) {
                    var instance, match, constructor, identifier;
                    later = later === true;
                    if (ident && isString(ident)) {
                        identifier = ident;
                    }
                    if (isString(expression)) {
                        match = expression.match(CNTRL_REG);
                        if (!match) {
                            throw $controllerMinErr('ctrlfmt',
                                "Badly formed controller string '{0}'. " +
                                "Must match `__name__ as __id__` or `__name__`.", expression);
                        }
                        constructor = match[1],
                            identifier = identifier || match[3];
                        expression = controllers.hasOwnProperty(constructor) ?
                            controllers[constructor] :
                            getter(locals.$scope, constructor, true) ||
                            (globals ? getter($window, constructor, true) : undefined);
                        assertArgFn(expression, constructor, true);
                    }
                    if (later) {
                        var controllerPrototype = (isArray(expression) ?
                            expression[expression.length - 1] : expression).prototype;
                        instance = Object.create(controllerPrototype || null);
                        if (identifier) {
                            addIdentifier(locals, identifier, instance, constructor || expression.name);
                        }
                        var instantiate;
                        return instantiate = extend(function $controllerInit() {
                            var result = $injector.invoke(expression, instance, locals, constructor);
                            if (result !== instance && (isObject(result) || isFunction(result))) {
                                instance = result;
                                if (identifier) {
                                    addIdentifier(locals, identifier, instance, constructor || expression.name);
                                }
                            }
                            return instance;
                        }, {
                            instance: instance,
                            identifier: identifier
                        });
                    }
                    instance = $injector.instantiate(expression, locals, constructor);
                    if (identifier) {
                        addIdentifier(locals, identifier, instance, constructor || expression.name);
                    }
                    return instance;
                };
    
                function addIdentifier(locals, identifier, instance, name) {
                    if (!(locals && isObject(locals.$scope))) {
                        throw minErr('$controller')('noscp',
                            "Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`.",
                            name, identifier);
                    }
                    locals.$scope[identifier] = instance;
                }
            }];
        }
    
        function $DocumentProvider() {
            this.$get = ['$window', function(window) {
                return jqLite(window.document);
            }];
        }
    
        function $ExceptionHandlerProvider() {
            this.$get = ['$log', function($log) {
                return function(exception, cause) {
                    $log.error.apply($log, arguments);
                };
            }];
        }
        var $$ForceReflowProvider = function() {
            this.$get = ['$document', function($document) {
                return function(domNode) {
                    if (domNode) {
                        if (!domNode.nodeType && domNode instanceof jqLite) {
                            domNode = domNode[0];
                        }
                    } else {
                        domNode = $document[0].body;
                    }
                    return domNode.offsetWidth + 1;
                };
            }];
        };
        var APPLICATION_JSON = 'application/json';
        var CONTENT_TYPE_APPLICATION_JSON = {
            'Content-Type': APPLICATION_JSON + ';charset=utf-8'
        };
        var JSON_START = /^\[|^\{(?!\{)/;
        var JSON_ENDS = {
            '[': /]$/,
            '{': /}$/
        };
        var JSON_PROTECTION_PREFIX = /^\)\]\}',?\n/;
        var $httpMinErr = minErr('$http');
        var $httpMinErrLegacyFn = function(method) {
            return function() {
                throw $httpMinErr('legacy', 'The method `{0}` on the promise returned from `$http` has been disabled.', method);
            };
        };
    
        function serializeValue(v) {
            if (isObject(v)) {
                return isDate(v) ? v.toISOString() : toJson(v);
            }
            return v;
        }
    
        function $HttpParamSerializerProvider() {
            this.$get = function() {
                return function ngParamSerializer(params) {
                    if (!params) return '';
                    var parts = [];
                    forEachSorted(params, function(value, key) {
                        if (value === null || isUndefined(value)) return;
                        if (isArray(value)) {
                            forEach(value, function(v) {
                                parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(serializeValue(v)));
                            });
                        } else {
                            parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(serializeValue(value)));
                        }
                    });
                    return parts.join('&');
                };
            };
        }
    
        function $HttpParamSerializerJQLikeProvider() {
            this.$get = function() {
                return function jQueryLikeParamSerializer(params) {
                    if (!params) return '';
                    var parts = [];
                    serialize(params, '', true);
                    return parts.join('&');
    
                    function serialize(toSerialize, prefix, topLevel) {
                        if (toSerialize === null || isUndefined(toSerialize)) return;
                        if (isArray(toSerialize)) {
                            forEach(toSerialize, function(value, index) {
                                serialize(value, prefix + '[' + (isObject(value) ? index : '') + ']');
                            });
                        } else if (isObject(toSerialize) && !isDate(toSerialize)) {
                            forEachSorted(toSerialize, function(value, key) {
                                serialize(value, prefix +
                                    (topLevel ? '' : '[') +
                                    key +
                                    (topLevel ? '' : ']'));
                            });
                        } else {
                            parts.push(encodeUriQuery(prefix) + '=' + encodeUriQuery(serializeValue(toSerialize)));
                        }
                    }
                };
            };
        }
    
        function defaultHttpResponseTransform(data, headers) {
            if (isString(data)) {
                var tempData = data.replace(JSON_PROTECTION_PREFIX, '').trim();
                if (tempData) {
                    var contentType = headers('Content-Type');
                    if ((contentType && (contentType.indexOf(APPLICATION_JSON) === 0)) || isJsonLike(tempData)) {
                        data = fromJson(tempData);
                    }
                }
            }
            return data;
        }
    
        function isJsonLike(str) {
            var jsonStart = str.match(JSON_START);
            return jsonStart && JSON_ENDS[jsonStart[0]].test(str);
        }
    
        function parseHeaders(headers) {
            var parsed = createMap(),
                i;
    
            function fillInParsed(key, val) {
                if (key) {
                    parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
                }
            }
            if (isString(headers)) {
                forEach(headers.split('\n'), function(line) {
                    i = line.indexOf(':');
                    fillInParsed(lowercase(trim(line.substr(0, i))), trim(line.substr(i + 1)));
                });
            } else if (isObject(headers)) {
                forEach(headers, function(headerVal, headerKey) {
                    fillInParsed(lowercase(headerKey), trim(headerVal));
                });
            }
            return parsed;
        }
    
        function headersGetter(headers) {
            var headersObj;
            return function(name) {
                if (!headersObj) headersObj = parseHeaders(headers);
                if (name) {
                    var value = headersObj[lowercase(name)];
                    if (value === void 0) {
                        value = null;
                    }
                    return value;
                }
                return headersObj;
            };
        }
    
        function transformData(data, headers, status, fns) {
            if (isFunction(fns)) {
                return fns(data, headers, status);
            }
            forEach(fns, function(fn) {
                data = fn(data, headers, status);
            });
            return data;
        }
    
        function isSuccess(status) {
            return 200 <= status && status < 300;
        }
    
        function $HttpProvider() {
            var defaults = this.defaults = {
                transformResponse: [defaultHttpResponseTransform],
                transformRequest: [function(d) {
                    return isObject(d) && !isFile(d) && !isBlob(d) && !isFormData(d) ? toJson(d) : d;
                }],
                headers: {
                    common: {
                        'Accept': 'application/json, text/plain, */*'
                    },
                    post: shallowCopy(CONTENT_TYPE_APPLICATION_JSON),
                    put: shallowCopy(CONTENT_TYPE_APPLICATION_JSON),
                    patch: shallowCopy(CONTENT_TYPE_APPLICATION_JSON)
                },
                xsrfCookieName: 'XSRF-TOKEN',
                xsrfHeaderName: 'X-XSRF-TOKEN',
                paramSerializer: '$httpParamSerializer'
            };
            var useApplyAsync = false;
            this.useApplyAsync = function(value) {
                if (isDefined(value)) {
                    useApplyAsync = !!value;
                    return this;
                }
                return useApplyAsync;
            };
            var useLegacyPromise = true;
            this.useLegacyPromiseExtensions = function(value) {
                if (isDefined(value)) {
                    useLegacyPromise = !!value;
                    return this;
                }
                return useLegacyPromise;
            };
            var interceptorFactories = this.interceptors = [];
            this.$get = ['$httpBackend', '$$cookieReader', '$cacheFactory', '$rootScope', '$q', '$injector',
                function($httpBackend, $$cookieReader, $cacheFactory, $rootScope, $q, $injector) {
                    var defaultCache = $cacheFactory('$http');
                    defaults.paramSerializer = isString(defaults.paramSerializer) ?
                        $injector.get(defaults.paramSerializer) : defaults.paramSerializer;
                    var reversedInterceptors = [];
                    forEach(interceptorFactories, function(interceptorFactory) {
                        reversedInterceptors.unshift(isString(interceptorFactory) ?
                            $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory));
                    });
    
                    function $http(requestConfig) {
                        if (!isObject(requestConfig)) {
                            throw minErr('$http')('badreq', 'Http request configuration must be an object.  Received: {0}', requestConfig);
                        }
                        if (!isString(requestConfig.url)) {
                            throw minErr('$http')('badreq', 'Http request configuration url must be a string.  Received: {0}', requestConfig.url);
                        }
                        var config = extend({
                            method: 'get',
                            transformRequest: defaults.transformRequest,
                            transformResponse: defaults.transformResponse,
                            paramSerializer: defaults.paramSerializer
                        }, requestConfig);
                        config.headers = mergeHeaders(requestConfig);
                        config.method = uppercase(config.method);
                        config.paramSerializer = isString(config.paramSerializer) ?
                            $injector.get(config.paramSerializer) : config.paramSerializer;
                        var serverRequest = function(config) {
                            var headers = config.headers;
                            var reqData = transformData(config.data, headersGetter(headers), undefined, config.transformRequest);
                            if (isUndefined(reqData)) {
                                forEach(headers, function(value, header) {
                                    if (lowercase(header) === 'content-type') {
                                        delete headers[header];
                                    }
                                });
                            }
                            if (isUndefined(config.withCredentials) && !isUndefined(defaults.withCredentials)) {
                                config.withCredentials = defaults.withCredentials;
                            }
                            return sendReq(config, reqData).then(transformResponse, transformResponse);
                        };
                        var chain = [serverRequest, undefined];
                        var promise = $q.when(config);
                        forEach(reversedInterceptors, function(interceptor) {
                            if (interceptor.request || interceptor.requestError) {
                                chain.unshift(interceptor.request, interceptor.requestError);
                            }
                            if (interceptor.response || interceptor.responseError) {
                                chain.push(interceptor.response, interceptor.responseError);
                            }
                        });
                        while (chain.length) {
                            var thenFn = chain.shift();
                            var rejectFn = chain.shift();
                            promise = promise.then(thenFn, rejectFn);
                        }
                        if (useLegacyPromise) {
                            promise.success = function(fn) {
                                assertArgFn(fn, 'fn');
                                promise.then(function(response) {
                                    fn(response.data, response.status, response.headers, config);
                                });
                                return promise;
                            };
                            promise.error = function(fn) {
                                assertArgFn(fn, 'fn');
                                promise.then(null, function(response) {
                                    fn(response.data, response.status, response.headers, config);
                                });
                                return promise;
                            };
                        } else {
                            promise.success = $httpMinErrLegacyFn('success');
                            promise.error = $httpMinErrLegacyFn('error');
                        }
                        return promise;
    
                        function transformResponse(response) {
                            var resp = extend({}, response);
                            resp.data = transformData(response.data, response.headers, response.status,
                                config.transformResponse);
                            return (isSuccess(response.status)) ?
                                resp :
                                $q.reject(resp);
                        }
    
                        function executeHeaderFns(headers, config) {
                            var headerContent, processedHeaders = {};
                            forEach(headers, function(headerFn, header) {
                                if (isFunction(headerFn)) {
                                    headerContent = headerFn(config);
                                    if (headerContent != null) {
                                        processedHeaders[header] = headerContent;
                                    }
                                } else {
                                    processedHeaders[header] = headerFn;
                                }
                            });
                            return processedHeaders;
                        }
    
                        function mergeHeaders(config) {
                            var defHeaders = defaults.headers,
                                reqHeaders = extend({}, config.headers),
                                defHeaderName, lowercaseDefHeaderName, reqHeaderName;
                            defHeaders = extend({}, defHeaders.common, defHeaders[lowercase(config.method)]);
                            defaultHeadersIteration:
                                for (defHeaderName in defHeaders) {
                                    lowercaseDefHeaderName = lowercase(defHeaderName);
                                    for (reqHeaderName in reqHeaders) {
                                        if (lowercase(reqHeaderName) === lowercaseDefHeaderName) {
                                            continue defaultHeadersIteration;
                                        }
                                    }
                                    reqHeaders[defHeaderName] = defHeaders[defHeaderName];
                                }
                            return executeHeaderFns(reqHeaders, shallowCopy(config));
                        }
                    }
                    $http.pendingRequests = [];
                    createShortMethods('get', 'delete', 'head', 'jsonp');
                    createShortMethodsWithData('post', 'put', 'patch');
                    $http.defaults = defaults;
                    return $http;
    
                    function createShortMethods(names) {
                        forEach(arguments, function(name) {
                            $http[name] = function(url, config) {
                                return $http(extend({}, config || {}, {
                                    method: name,
                                    url: url
                                }));
                            };
                        });
                    }
    
                    function createShortMethodsWithData(name) {
                        forEach(arguments, function(name) {
                            $http[name] = function(url, data, config) {
                                return $http(extend({}, config || {}, {
                                    method: name,
                                    url: url,
                                    data: data
                                }));
                            };
                        });
                    }
    
                    function sendReq(config, reqData) {
                        var deferred = $q.defer(),
                            promise = deferred.promise,
                            cache,
                            cachedResp,
                            reqHeaders = config.headers,
                            url = buildUrl(config.url, config.paramSerializer(config.params));
                        $http.pendingRequests.push(config);
                        promise.then(removePendingReq, removePendingReq);
                        if ((config.cache || defaults.cache) && config.cache !== false &&
                            (config.method === 'GET' || config.method === 'JSONP')) {
                            cache = isObject(config.cache) ? config.cache :
                                isObject(defaults.cache) ? defaults.cache :
                                defaultCache;
                        }
                        if (cache) {
                            cachedResp = cache.get(url);
                            if (isDefined(cachedResp)) {
                                if (isPromiseLike(cachedResp)) {
                                    cachedResp.then(resolvePromiseWithResult, resolvePromiseWithResult);
                                } else {
                                    if (isArray(cachedResp)) {
                                        resolvePromise(cachedResp[1], cachedResp[0], shallowCopy(cachedResp[2]), cachedResp[3]);
                                    } else {
                                        resolvePromise(cachedResp, 200, {}, 'OK');
                                    }
                                }
                            } else {
                                cache.put(url, promise);
                            }
                        }
                        if (isUndefined(cachedResp)) {
                            var xsrfValue = urlIsSameOrigin(config.url) ?
                                $$cookieReader()[config.xsrfCookieName || defaults.xsrfCookieName] :
                                undefined;
                            if (xsrfValue) {
                                reqHeaders[(config.xsrfHeaderName || defaults.xsrfHeaderName)] = xsrfValue;
                            }
                            $httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout,
                                config.withCredentials, config.responseType);
                        }
                        return promise;
    
                        function done(status, response, headersString, statusText) {
                            if (cache) {
                                if (isSuccess(status)) {
                                    cache.put(url, [status, response, parseHeaders(headersString), statusText]);
                                } else {
                                    cache.remove(url);
                                }
                            }
    
                            function resolveHttpPromise() {
                                resolvePromise(response, status, headersString, statusText);
                            }
                            if (useApplyAsync) {
                                $rootScope.$applyAsync(resolveHttpPromise);
                            } else {
                                resolveHttpPromise();
                                if (!$rootScope.$$phase) $rootScope.$apply();
                            }
                        }
    
                        function resolvePromise(response, status, headers, statusText) {
                            status = status >= -1 ? status : 0;
                            (isSuccess(status) ? deferred.resolve : deferred.reject)({
                                data: response,
                                status: status,
                                headers: headersGetter(headers),
                                config: config,
                                statusText: statusText
                            });
                        }
    
                        function resolvePromiseWithResult(result) {
                            resolvePromise(result.data, result.status, shallowCopy(result.headers()), result.statusText);
                        }
    
                        function removePendingReq() {
                            var idx = $http.pendingRequests.indexOf(config);
                            if (idx !== -1) $http.pendingRequests.splice(idx, 1);
                        }
                    }
    
                    function buildUrl(url, serializedParams) {
                        if (serializedParams.length > 0) {
                            url += ((url.indexOf('?') == -1) ? '?' : '&') + serializedParams;
                        }
                        return url;
                    }
                }
            ];
        }
    
        function $xhrFactoryProvider() {
            this.$get = function() {
                return function createXhr() {
                    return new window.XMLHttpRequest();
                };
            };
        }
    
        function $HttpBackendProvider() {
            this.$get = ['$browser', '$window', '$document', '$xhrFactory', function($browser, $window, $document, $xhrFactory) {
                return createHttpBackend($browser, $xhrFactory, $browser.defer, $window.angular.callbacks, $document[0]);
            }];
        }
    
        function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDocument) {
            return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
                $browser.$$incOutstandingRequestCount();
                url = url || $browser.url();
                if (lowercase(method) == 'jsonp') {
                    var callbackId = '_' + (callbacks.counter++).toString(36);
                    callbacks[callbackId] = function(data) {
                        callbacks[callbackId].data = data;
                        callbacks[callbackId].called = true;
                    };
                    var jsonpDone = jsonpReq(url.replace('JSON_CALLBACK', 'angular.callbacks.' + callbackId),
                        callbackId,
                        function(status, text) {
                            completeRequest(callback, status, callbacks[callbackId].data, "", text);
                            callbacks[callbackId] = noop;
                        });
                } else {
                    var xhr = createXhr(method, url);
                    xhr.open(method, url, true);
                    forEach(headers, function(value, key) {
                        if (isDefined(value)) {
                            xhr.setRequestHeader(key, value);
                        }
                    });
                    xhr.onload = function requestLoaded() {
                        var statusText = xhr.statusText || '';
                        var response = ('response' in xhr) ? xhr.response : xhr.responseText;
                        var status = xhr.status === 1223 ? 204 : xhr.status;
                        if (status === 0) {
                            status = response ? 200 : urlResolve(url).protocol == 'file' ? 404 : 0;
                        }
                        completeRequest(callback,
                            status,
                            response,
                            xhr.getAllResponseHeaders(),
                            statusText);
                    };
                    var requestError = function() {
                        completeRequest(callback, -1, null, null, '');
                    };
                    xhr.onerror = requestError;
                    xhr.onabort = requestError;
                    if (withCredentials) {
                        xhr.withCredentials = true;
                    }
                    if (responseType) {
                        try {
                            xhr.responseType = responseType;
                        } catch (e) {
                            if (responseType !== 'json') {
                                throw e;
                            }
                        }
                    }
                    xhr.send(isUndefined(post) ? null : post);
                }
                if (timeout > 0) {
                    var timeoutId = $browserDefer(timeoutRequest, timeout);
                } else if (isPromiseLike(timeout)) {
                    timeout.then(timeoutRequest);
                }
    
                function timeoutRequest() {
                    jsonpDone && jsonpDone();
                    xhr && xhr.abort();
                }
    
                function completeRequest(callback, status, response, headersString, statusText) {
                    if (isDefined(timeoutId)) {
                        $browserDefer.cancel(timeoutId);
                    }
                    jsonpDone = xhr = null;
                    callback(status, response, headersString, statusText);
                    $browser.$$completeOutstandingRequest(noop);
                }
            };
    
            function jsonpReq(url, callbackId, done) {
                var script = rawDocument.createElement('script'),
                    callback = null;
                script.type = "text/javascript";
                script.src = url;
                script.async = true;
                callback = function(event) {
                    removeEventListenerFn(script, "load", callback);
                    removeEventListenerFn(script, "error", callback);
                    rawDocument.body.removeChild(script);
                    script = null;
                    var status = -1;
                    var text = "unknown";
                    if (event) {
                        if (event.type === "load" && !callbacks[callbackId].called) {
                            event = {
                                type: "error"
                            };
                        }
                        text = event.type;
                        status = event.type === "error" ? 404 : 200;
                    }
                    if (done) {
                        done(status, text);
                    }
                };
                addEventListenerFn(script, "load", callback);
                addEventListenerFn(script, "error", callback);
                rawDocument.body.appendChild(script);
                return callback;
            }
        }
        var $interpolateMinErr = angular.$interpolateMinErr = minErr('$interpolate');
        $interpolateMinErr.throwNoconcat = function(text) {
            throw $interpolateMinErr('noconcat',
                "Error while interpolating: {0}\nStrict Contextual Escaping disallows " +
                "interpolations that concatenate multiple expressions when a trusted value is " +
                "required.  See http://docs.angularjs.org/api/ng.$sce", text);
        };
        $interpolateMinErr.interr = function(text, err) {
            return $interpolateMinErr('interr', "Can't interpolate: {0}\n{1}", text, err.toString());
        };
    
        function $InterpolateProvider() {
            var startSymbol = '{{';
            var endSymbol = '}}';
            this.startSymbol = function(value) {
                if (value) {
                    startSymbol = value;
                    return this;
                } else {
                    return startSymbol;
                }
            };
            this.endSymbol = function(value) {
                if (value) {
                    endSymbol = value;
                    return this;
                } else {
                    return endSymbol;
                }
            };
            this.$get = ['$parse', '$exceptionHandler', '$sce', function($parse, $exceptionHandler, $sce) {
                var startSymbolLength = startSymbol.length,
                    endSymbolLength = endSymbol.length,
                    escapedStartRegexp = new RegExp(startSymbol.replace(/./g, escape), 'g'),
                    escapedEndRegexp = new RegExp(endSymbol.replace(/./g, escape), 'g');
    
                function escape(ch) {
                    return '\\\\\\' + ch;
                }
    
                function unescapeText(text) {
                    return text.replace(escapedStartRegexp, startSymbol).
                    replace(escapedEndRegexp, endSymbol);
                }
    
                function stringify(value) {
                    if (value == null) {
                        return '';
                    }
                    switch (typeof value) {
                        case 'string':
                            break;
                        case 'number':
                            value = '' + value;
                            break;
                        default:
                            value = toJson(value);
                    }
                    return value;
                }
    
                function constantWatchDelegate(scope, listener, objectEquality, constantInterp) {
                    var unwatch;
                    return unwatch = scope.$watch(function constantInterpolateWatch(scope) {
                        unwatch();
                        return constantInterp(scope);
                    }, listener, objectEquality);
                }
    
                function $interpolate(text, mustHaveExpression, trustedContext, allOrNothing) {
                    if (!text.length || text.indexOf(startSymbol) === -1) {
                        var constantInterp;
                        if (!mustHaveExpression) {
                            var unescapedText = unescapeText(text);
                            constantInterp = valueFn(unescapedText);
                            constantInterp.exp = text;
                            constantInterp.expressions = [];
                            constantInterp.$$watchDelegate = constantWatchDelegate;
                        }
                        return constantInterp;
                    }
                    allOrNothing = !!allOrNothing;
                    var startIndex,
                        endIndex,
                        index = 0,
                        expressions = [],
                        parseFns = [],
                        textLength = text.length,
                        exp,
                        concat = [],
                        expressionPositions = [];
                    while (index < textLength) {
                        if (((startIndex = text.indexOf(startSymbol, index)) != -1) &&
                            ((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) != -1)) {
                            if (index !== startIndex) {
                                concat.push(unescapeText(text.substring(index, startIndex)));
                            }
                            exp = text.substring(startIndex + startSymbolLength, endIndex);
                            expressions.push(exp);
                            parseFns.push($parse(exp, parseStringifyInterceptor));
                            index = endIndex + endSymbolLength;
                            expressionPositions.push(concat.length);
                            concat.push('');
                        } else {
                            if (index !== textLength) {
                                concat.push(unescapeText(text.substring(index)));
                            }
                            break;
                        }
                    }
                    if (trustedContext && concat.length > 1) {
                        $interpolateMinErr.throwNoconcat(text);
                    }
                    if (!mustHaveExpression || expressions.length) {
                        var compute = function(values) {
                            for (var i = 0, ii = expressions.length; i < ii; i++) {
                                if (allOrNothing && isUndefined(values[i])) return;
                                concat[expressionPositions[i]] = values[i];
                            }
                            return concat.join('');
                        };
                        var getValue = function(value) {
                            return trustedContext ?
                                $sce.getTrusted(trustedContext, value) :
                                $sce.valueOf(value);
                        };
                        return extend(function interpolationFn(context) {
                            var i = 0;
                            var ii = expressions.length;
                            var values = new Array(ii);
                            try {
                                for (; i < ii; i++) {
                                    values[i] = parseFns[i](context);
                                }
                                return compute(values);
                            } catch (err) {
                                $exceptionHandler($interpolateMinErr.interr(text, err));
                            }
                        }, {
                            exp: text,
                            expressions: expressions,
                            $$watchDelegate: function(scope, listener) {
                                var lastValue;
                                return scope.$watchGroup(parseFns, function interpolateFnWatcher(values, oldValues) {
                                    var currValue = compute(values);
                                    if (isFunction(listener)) {
                                        listener.call(this, currValue, values !== oldValues ? lastValue : currValue, scope);
                                    }
                                    lastValue = currValue;
                                });
                            }
                        });
                    }
    
                    function parseStringifyInterceptor(value) {
                        try {
                            value = getValue(value);
                            return allOrNothing && !isDefined(value) ? value : stringify(value);
                        } catch (err) {
                            $exceptionHandler($interpolateMinErr.interr(text, err));
                        }
                    }
                }
                $interpolate.startSymbol = function() {
                    return startSymbol;
                };
                $interpolate.endSymbol = function() {
                    return endSymbol;
                };
                return $interpolate;
            }];
        }
    
        function $IntervalProvider() {
            this.$get = ['$rootScope', '$window', '$q', '$$q', '$browser',
                function($rootScope, $window, $q, $$q, $browser) {
                    var intervals = {};
    
                    function interval(fn, delay, count, invokeApply) {
                        var hasParams = arguments.length > 4,
                            args = hasParams ? sliceArgs(arguments, 4) : [],
                            setInterval = $window.setInterval,
                            clearInterval = $window.clearInterval,
                            iteration = 0,
                            skipApply = (isDefined(invokeApply) && !invokeApply),
                            deferred = (skipApply ? $$q : $q).defer(),
                            promise = deferred.promise;
                        count = isDefined(count) ? count : 0;
                        promise.$$intervalId = setInterval(function tick() {
                            if (skipApply) {
                                $browser.defer(callback);
                            } else {
                                $rootScope.$evalAsync(callback);
                            }
                            deferred.notify(iteration++);
                            if (count > 0 && iteration >= count) {
                                deferred.resolve(iteration);
                                clearInterval(promise.$$intervalId);
                                delete intervals[promise.$$intervalId];
                            }
                            if (!skipApply) $rootScope.$apply();
                        }, delay);
                        intervals[promise.$$intervalId] = deferred;
                        return promise;
    
                        function callback() {
                            if (!hasParams) {
                                fn(iteration);
                            } else {
                                fn.apply(null, args);
                            }
                        }
                    }
                    interval.cancel = function(promise) {
                        if (promise && promise.$$intervalId in intervals) {
                            intervals[promise.$$intervalId].reject('canceled');
                            $window.clearInterval(promise.$$intervalId);
                            delete intervals[promise.$$intervalId];
                            return true;
                        }
                        return false;
                    };
                    return interval;
                }
            ];
        }
        var PATH_MATCH = /^([^\?#]*)(\?([^#]*))?(#(.*))?$/,
            DEFAULT_PORTS = {
                'http': 80,
                'https': 443,
                'ftp': 21
            };
        var $locationMinErr = minErr('$location');
    
        function encodePath(path) {
            var segments = path.split('/'),
                i = segments.length;
            while (i--) {
                segments[i] = encodeUriSegment(segments[i]);
            }
            return segments.join('/');
        }
    
        function parseAbsoluteUrl(absoluteUrl, locationObj) {
            var parsedUrl = urlResolve(absoluteUrl);
            locationObj.$$protocol = parsedUrl.protocol;
            locationObj.$$host = parsedUrl.hostname;
            locationObj.$$port = toInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null;
        }
    
        function parseAppUrl(relativeUrl, locationObj) {
            var prefixed = (relativeUrl.charAt(0) !== '/');
            if (prefixed) {
                relativeUrl = '/' + relativeUrl;
            }
            var match = urlResolve(relativeUrl);
            locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ?
                match.pathname.substring(1) : match.pathname);
            locationObj.$$search = parseKeyValue(match.search);
            locationObj.$$hash = decodeURIComponent(match.hash);
            if (locationObj.$$path && locationObj.$$path.charAt(0) != '/') {
                locationObj.$$path = '/' + locationObj.$$path;
            }
        }
    
        function beginsWith(begin, whole) {
            if (whole.indexOf(begin) === 0) {
                return whole.substr(begin.length);
            }
        }
    
        function stripHash(url) {
            var index = url.indexOf('#');
            return index == -1 ? url : url.substr(0, index);
        }
    
        function trimEmptyHash(url) {
            return url.replace(/(#.+)|#$/, '$1');
        }
    
        function stripFile(url) {
            return url.substr(0, stripHash(url).lastIndexOf('/') + 1);
        }
    
        function serverBase(url) {
            return url.substring(0, url.indexOf('/', url.indexOf('//') + 2));
        }
    
        function LocationHtml5Url(appBase, appBaseNoFile, basePrefix) {
            this.$$html5 = true;
            basePrefix = basePrefix || '';
            parseAbsoluteUrl(appBase, this);
            this.$$parse = function(url) {
                var pathUrl = beginsWith(appBaseNoFile, url);
                if (!isString(pathUrl)) {
                    throw $locationMinErr('ipthprfx', 'Invalid url "{0}", missing path prefix "{1}".', url,
                        appBaseNoFile);
                }
                parseAppUrl(pathUrl, this);
                if (!this.$$path) {
                    this.$$path = '/';
                }
                this.$$compose();
            };
            this.$$compose = function() {
                var search = toKeyValue(this.$$search),
                    hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';
                this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;
                this.$$absUrl = appBaseNoFile + this.$$url.substr(1);
            };
            this.$$parseLinkUrl = function(url, relHref) {
                if (relHref && relHref[0] === '#') {
                    this.hash(relHref.slice(1));
                    return true;
                }
                var appUrl, prevAppUrl;
                var rewrittenUrl;
                if (isDefined(appUrl = beginsWith(appBase, url))) {
                    prevAppUrl = appUrl;
                    if (isDefined(appUrl = beginsWith(basePrefix, appUrl))) {
                        rewrittenUrl = appBaseNoFile + (beginsWith('/', appUrl) || appUrl);
                    } else {
                        rewrittenUrl = appBase + prevAppUrl;
                    }
                } else if (isDefined(appUrl = beginsWith(appBaseNoFile, url))) {
                    rewrittenUrl = appBaseNoFile + appUrl;
                } else if (appBaseNoFile == url + '/') {
                    rewrittenUrl = appBaseNoFile;
                }
                if (rewrittenUrl) {
                    this.$$parse(rewrittenUrl);
                }
                return !!rewrittenUrl;
            };
        }
    
        function LocationHashbangUrl(appBase, appBaseNoFile, hashPrefix) {
            parseAbsoluteUrl(appBase, this);
            this.$$parse = function(url) {
                var withoutBaseUrl = beginsWith(appBase, url) || beginsWith(appBaseNoFile, url);
                var withoutHashUrl;
                if (!isUndefined(withoutBaseUrl) && withoutBaseUrl.charAt(0) === '#') {
                    withoutHashUrl = beginsWith(hashPrefix, withoutBaseUrl);
                    if (isUndefined(withoutHashUrl)) {
                        withoutHashUrl = withoutBaseUrl;
                    }
                } else {
                    if (this.$$html5) {
                        withoutHashUrl = withoutBaseUrl;
                    } else {
                        withoutHashUrl = '';
                        if (isUndefined(withoutBaseUrl)) {
                            appBase = url;
                            this.replace();
                        }
                    }
                }
                parseAppUrl(withoutHashUrl, this);
                this.$$path = removeWindowsDriveName(this.$$path, withoutHashUrl, appBase);
                this.$$compose();
    
                function removeWindowsDriveName(path, url, base) {
                    var windowsFilePathExp = /^\/[A-Z]:(\/.*)/;
                    var firstPathSegmentMatch;
                    if (url.indexOf(base) === 0) {
                        url = url.replace(base, '');
                    }
                    if (windowsFilePathExp.exec(url)) {
                        return path;
                    }
                    firstPathSegmentMatch = windowsFilePathExp.exec(path);
                    return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path;
                }
            };
            this.$$compose = function() {
                var search = toKeyValue(this.$$search),
                    hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';
                this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;
                this.$$absUrl = appBase + (this.$$url ? hashPrefix + this.$$url : '');
            };
            this.$$parseLinkUrl = function(url, relHref) {
                if (stripHash(appBase) == stripHash(url)) {
                    this.$$parse(url);
                    return true;
                }
                return false;
            };
        }
    
        function LocationHashbangInHtml5Url(appBase, appBaseNoFile, hashPrefix) {
            this.$$html5 = true;
            LocationHashbangUrl.apply(this, arguments);
            this.$$parseLinkUrl = function(url, relHref) {
                if (relHref && relHref[0] === '#') {
                    this.hash(relHref.slice(1));
                    return true;
                }
                var rewrittenUrl;
                var appUrl;
                if (appBase == stripHash(url)) {
                    rewrittenUrl = url;
                } else if ((appUrl = beginsWith(appBaseNoFile, url))) {
                    rewrittenUrl = appBase + hashPrefix + appUrl;
                } else if (appBaseNoFile === url + '/') {
                    rewrittenUrl = appBaseNoFile;
                }
                if (rewrittenUrl) {
                    this.$$parse(rewrittenUrl);
                }
                return !!rewrittenUrl;
            };
            this.$$compose = function() {
                var search = toKeyValue(this.$$search),
                    hash = this.$$hash ? '#' + encodeUriSegment(this.$$hash) : '';
                this.$$url = encodePath(this.$$path) + (search ? '?' + search : '') + hash;
                this.$$absUrl = appBase + hashPrefix + this.$$url;
            };
        }
        var locationPrototype = {
            $$html5: false,
            $$replace: false,
            absUrl: locationGetter('$$absUrl'),
            url: function(url) {
                if (isUndefined(url)) {
                    return this.$$url;
                }
                var match = PATH_MATCH.exec(url);
                if (match[1] || url === '') this.path(decodeURIComponent(match[1]));
                if (match[2] || match[1] || url === '') this.search(match[3] || '');
                this.hash(match[5] || '');
                return this;
            },
            protocol: locationGetter('$$protocol'),
            host: locationGetter('$$host'),
            port: locationGetter('$$port'),
            path: locationGetterSetter('$$path', function(path) {
                path = path !== null ? path.toString() : '';
                return path.charAt(0) == '/' ? path : '/' + path;
            }),
            search: function(search, paramValue) {
                switch (arguments.length) {
                    case 0:
                        return this.$$search;
                    case 1:
                        if (isString(search) || isNumber(search)) {
                            search = search.toString();
                            this.$$search = parseKeyValue(search);
                        } else if (isObject(search)) {
                            search = copy(search, {});
                            forEach(search, function(value, key) {
                                if (value == null) delete search[key];
                            });
                            this.$$search = search;
                        } else {
                            throw $locationMinErr('isrcharg',
                                'The first argument of the `$location#search()` call must be a string or an object.');
                        }
                        break;
                    default:
                        if (isUndefined(paramValue) || paramValue === null) {
                            delete this.$$search[search];
                        } else {
                            this.$$search[search] = paramValue;
                        }
                }
                this.$$compose();
                return this;
            },
            hash: locationGetterSetter('$$hash', function(hash) {
                return hash !== null ? hash.toString() : '';
            }),
            replace: function() {
                this.$$replace = true;
                return this;
            }
        };
        forEach([LocationHashbangInHtml5Url, LocationHashbangUrl, LocationHtml5Url], function(Location) {
            Location.prototype = Object.create(locationPrototype);
            Location.prototype.state = function(state) {
                if (!arguments.length) {
                    return this.$$state;
                }
                if (Location !== LocationHtml5Url || !this.$$html5) {
                    throw $locationMinErr('nostate', 'History API state support is available only ' +
                        'in HTML5 mode and only in browsers supporting HTML5 History API');
                }
                this.$$state = isUndefined(state) ? null : state;
                return this;
            };
        });
    
        function locationGetter(property) {
            return function() {
                return this[property];
            };
        }
    
        function locationGetterSetter(property, preprocess) {
            return function(value) {
                if (isUndefined(value)) {
                    return this[property];
                }
                this[property] = preprocess(value);
                this.$$compose();
                return this;
            };
        }
    
        function $LocationProvider() {
            var hashPrefix = '',
                html5Mode = {
                    enabled: false,
                    requireBase: true,
                    rewriteLinks: true
                };
            this.hashPrefix = function(prefix) {
                if (isDefined(prefix)) {
                    hashPrefix = prefix;
                    return this;
                } else {
                    return hashPrefix;
                }
            };
            this.html5Mode = function(mode) {
                if (isBoolean(mode)) {
                    html5Mode.enabled = mode;
                    return this;
                } else if (isObject(mode)) {
                    if (isBoolean(mode.enabled)) {
                        html5Mode.enabled = mode.enabled;
                    }
                    if (isBoolean(mode.requireBase)) {
                        html5Mode.requireBase = mode.requireBase;
                    }
                    if (isBoolean(mode.rewriteLinks)) {
                        html5Mode.rewriteLinks = mode.rewriteLinks;
                    }
                    return this;
                } else {
                    return html5Mode;
                }
            };
            this.$get = ['$rootScope', '$browser', '$sniffer', '$rootElement', '$window',
                function($rootScope, $browser, $sniffer, $rootElement, $window) {
                    var $location,
                        LocationMode,
                        baseHref = $browser.baseHref(),
                        initialUrl = $browser.url(),
                        appBase;
                    if (html5Mode.enabled) {
                        if (!baseHref && html5Mode.requireBase) {
                            throw $locationMinErr('nobase',
                                "$location in HTML5 mode requires a <base> tag to be present!");
                        }
                        appBase = serverBase(initialUrl) + (baseHref || '/');
                        LocationMode = $sniffer.history ? LocationHtml5Url : LocationHashbangInHtml5Url;
                    } else {
                        appBase = stripHash(initialUrl);
                        LocationMode = LocationHashbangUrl;
                    }
                    var appBaseNoFile = stripFile(appBase);
                    $location = new LocationMode(appBase, appBaseNoFile, '#' + hashPrefix);
                    $location.$$parseLinkUrl(initialUrl, initialUrl);
                    $location.$$state = $browser.state();
                    var IGNORE_URI_REGEXP = /^\s*(javascript|mailto):/i;
    
                    function setBrowserUrlWithFallback(url, replace, state) {
                        var oldUrl = $location.url();
                        var oldState = $location.$$state;
                        try {
                            $browser.url(url, replace, state);
                            $location.$$state = $browser.state();
                        } catch (e) {
                            $location.url(oldUrl);
                            $location.$$state = oldState;
                            throw e;
                        }
                    }
                    $rootElement.on('click', function(event) {
                        if (!html5Mode.rewriteLinks || event.ctrlKey || event.metaKey || event.shiftKey || event.which == 2 || event.button == 2) return;
                        var elm = jqLite(event.target);
                        while (nodeName_(elm[0]) !== 'a') {
                            if (elm[0] === $rootElement[0] || !(elm = elm.parent())[0]) return;
                        }
                        var absHref = elm.prop('href');
                        var relHref = elm.attr('href') || elm.attr('xlink:href');
                        if (isObject(absHref) && absHref.toString() === '[object SVGAnimatedString]') {
                            absHref = urlResolve(absHref.animVal).href;
                        }
                        if (IGNORE_URI_REGEXP.test(absHref)) return;
                        if (absHref && !elm.attr('target') && !event.isDefaultPrevented()) {
                            if ($location.$$parseLinkUrl(absHref, relHref)) {
                                event.preventDefault();
                                if ($location.absUrl() != $browser.url()) {
                                    $rootScope.$apply();
                                    $window.angular['ff-684208-preventDefault'] = true;
                                }
                            }
                        }
                    });
                    if (trimEmptyHash($location.absUrl()) != trimEmptyHash(initialUrl)) {
                        $browser.url($location.absUrl(), true);
                    }
                    var initializing = true;
                    $browser.onUrlChange(function(newUrl, newState) {
                        if (isUndefined(beginsWith(appBaseNoFile, newUrl))) {
                            $window.location.href = newUrl;
                            return;
                        }
                        $rootScope.$evalAsync(function() {
                            var oldUrl = $location.absUrl();
                            var oldState = $location.$$state;
                            var defaultPrevented;
                            newUrl = trimEmptyHash(newUrl);
                            $location.$$parse(newUrl);
                            $location.$$state = newState;
                            defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,
                                newState, oldState).defaultPrevented;
                            if ($location.absUrl() !== newUrl) return;
                            if (defaultPrevented) {
                                $location.$$parse(oldUrl);
                                $location.$$state = oldState;
                                setBrowserUrlWithFallback(oldUrl, false, oldState);
                            } else {
                                initializing = false;
                                afterLocationChange(oldUrl, oldState);
                            }
                        });
                        if (!$rootScope.$$phase) $rootScope.$digest();
                    });
                    $rootScope.$watch(function $locationWatch() {
                        var oldUrl = trimEmptyHash($browser.url());
                        var newUrl = trimEmptyHash($location.absUrl());
                        var oldState = $browser.state();
                        var currentReplace = $location.$$replace;
                        var urlOrStateChanged = oldUrl !== newUrl ||
                            ($location.$$html5 && $sniffer.history && oldState !== $location.$$state);
                        if (initializing || urlOrStateChanged) {
                            initializing = false;
                            $rootScope.$evalAsync(function() {
                                var newUrl = $location.absUrl();
                                var defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,
                                    $location.$$state, oldState).defaultPrevented;
                                if ($location.absUrl() !== newUrl) return;
                                if (defaultPrevented) {
                                    $location.$$parse(oldUrl);
                                    $location.$$state = oldState;
                                } else {
                                    if (urlOrStateChanged) {
                                        setBrowserUrlWithFallback(newUrl, currentReplace,
                                            oldState === $location.$$state ? null : $location.$$state);
                                    }
                                    afterLocationChange(oldUrl, oldState);
                                }
                            });
                        }
                        $location.$$replace = false;
                    });
                    return $location;
    
                    function afterLocationChange(oldUrl, oldState) {
                        $rootScope.$broadcast('$locationChangeSuccess', $location.absUrl(), oldUrl,
                            $location.$$state, oldState);
                    }
                }
            ];
        }
    
        function $LogProvider() {
            var debug = true,
                self = this;
            this.debugEnabled = function(flag) {
                if (isDefined(flag)) {
                    debug = flag;
                    return this;
                } else {
                    return debug;
                }
            };
            this.$get = ['$window', function($window) {
                return {
                    log: consoleLog('log'),
                    info: consoleLog('info'),
                    warn: consoleLog('warn'),
                    error: consoleLog('error'),
                    debug: (function() {
                        var fn = consoleLog('debug');
                        return function() {
                            if (debug) {
                                fn.apply(self, arguments);
                            }
                        };
                    }())
                };
    
                function formatError(arg) {
                    if (arg instanceof Error) {
                        if (arg.stack) {
                            arg = (arg.message && arg.stack.indexOf(arg.message) === -1) ?
                                'Error: ' + arg.message + '\n' + arg.stack :
                                arg.stack;
                        } else if (arg.sourceURL) {
                            arg = arg.message + '\n' + arg.sourceURL + ':' + arg.line;
                        }
                    }
                    return arg;
                }
    
                function consoleLog(type) {
                    var console = $window.console || {},
                        logFn = console[type] || console.log || noop,
                        hasApply = false;
                    try {
                        hasApply = !!logFn.apply;
                    } catch (e) {}
                    if (hasApply) {
                        return function() {
                            var args = [];
                            forEach(arguments, function(arg) {
                                args.push(formatError(arg));
                            });
                            return logFn.apply(console, args);
                        };
                    }
                    return function(arg1, arg2) {
                        logFn(arg1, arg2 == null ? '' : arg2);
                    };
                }
            }];
        }
        var $parseMinErr = minErr('$parse');
    
        function ensureSafeMemberName(name, fullExpression) {
            if (name === "__defineGetter__" || name === "__defineSetter__" ||
                name === "__lookupGetter__" || name === "__lookupSetter__" ||
                name === "__proto__") {
                throw $parseMinErr('isecfld',
                    'Attempting to access a disallowed field in Angular expressions! ' +
                    'Expression: {0}', fullExpression);
            }
            return name;
        }
    
        function getStringValue(name) {
            return name + '';
        }
    
        function ensureSafeObject(obj, fullExpression) {
            if (obj) {
                if (obj.constructor === obj) {
                    throw $parseMinErr('isecfn',
                        'Referencing Function in Angular expressions is disallowed! Expression: {0}',
                        fullExpression);
                } else if (
                    obj.window === obj) {
                    throw $parseMinErr('isecwindow',
                        'Referencing the Window in Angular expressions is disallowed! Expression: {0}',
                        fullExpression);
                } else if (
                    obj.children && (obj.nodeName || (obj.prop && obj.attr && obj.find))) {
                    throw $parseMinErr('isecdom',
                        'Referencing DOM nodes in Angular expressions is disallowed! Expression: {0}',
                        fullExpression);
                } else if (
                    obj === Object) {
                    throw $parseMinErr('isecobj',
                        'Referencing Object in Angular expressions is disallowed! Expression: {0}',
                        fullExpression);
                }
            }
            return obj;
        }
        var CALL = Function.prototype.call;
        var APPLY = Function.prototype.apply;
        var BIND = Function.prototype.bind;
    
        function ensureSafeFunction(obj, fullExpression) {
            if (obj) {
                if (obj.constructor === obj) {
                    throw $parseMinErr('isecfn',
                        'Referencing Function in Angular expressions is disallowed! Expression: {0}',
                        fullExpression);
                } else if (obj === CALL || obj === APPLY || obj === BIND) {
                    throw $parseMinErr('isecff',
                        'Referencing call, apply or bind in Angular expressions is disallowed! Expression: {0}',
                        fullExpression);
                }
            }
        }
    
        function ensureSafeAssignContext(obj, fullExpression) {
            if (obj) {
                if (obj === (0).constructor || obj === (false).constructor || obj === ''.constructor ||
                    obj === {}.constructor || obj === [].constructor || obj === Function.constructor) {
                    throw $parseMinErr('isecaf',
                        'Assigning to a constructor is disallowed! Expression: {0}', fullExpression);
                }
            }
        }
        var OPERATORS = createMap();
        forEach('+ - * / % === !== == != < > <= >= && || ! = |'.split(' '), function(operator) {
            OPERATORS[operator] = true;
        });
        var ESCAPE = {
            "n": "\n",
            "f": "\f",
            "r": "\r",
            "t": "\t",
            "v": "\v",
            "'": "'",
            '"': '"'
        };
        var Lexer = function(options) {
            this.options = options;
        };
        Lexer.prototype = {
            constructor: Lexer,
            lex: function(text) {
                this.text = text;
                this.index = 0;
                this.tokens = [];
                while (this.index < this.text.length) {
                    var ch = this.text.charAt(this.index);
                    if (ch === '"' || ch === "'") {
                        this.readString(ch);
                    } else if (this.isNumber(ch) || ch === '.' && this.isNumber(this.peek())) {
                        this.readNumber();
                    } else if (this.isIdent(ch)) {
                        this.readIdent();
                    } else if (this.is(ch, '(){}[].,;:?')) {
                        this.tokens.push({
                            index: this.index,
                            text: ch
                        });
                        this.index++;
                    } else if (this.isWhitespace(ch)) {
                        this.index++;
                    } else {
                        var ch2 = ch + this.peek();
                        var ch3 = ch2 + this.peek(2);
                        var op1 = OPERATORS[ch];
                        var op2 = OPERATORS[ch2];
                        var op3 = OPERATORS[ch3];
                        if (op1 || op2 || op3) {
                            var token = op3 ? ch3 : (op2 ? ch2 : ch);
                            this.tokens.push({
                                index: this.index,
                                text: token,
                                operator: true
                            });
                            this.index += token.length;
                        } else {
                            this.throwError('Unexpected next character ', this.index, this.index + 1);
                        }
                    }
                }
                return this.tokens;
            },
            is: function(ch, chars) {
                return chars.indexOf(ch) !== -1;
            },
            peek: function(i) {
                var num = i || 1;
                return (this.index + num < this.text.length) ? this.text.charAt(this.index + num) : false;
            },
            isNumber: function(ch) {
                return ('0' <= ch && ch <= '9') && typeof ch === "string";
            },
            isWhitespace: function(ch) {
                return (ch === ' ' || ch === '\r' || ch === '\t' ||
                    ch === '\n' || ch === '\v' || ch === '\u00A0');
            },
            isIdent: function(ch) {
                return ('a' <= ch && ch <= 'z' ||
                    'A' <= ch && ch <= 'Z' ||
                    '_' === ch || ch === '$');
            },
            isExpOperator: function(ch) {
                return (ch === '-' || ch === '+' || this.isNumber(ch));
            },
            throwError: function(error, start, end) {
                end = end || this.index;
                var colStr = (isDefined(start) ?
                    's ' + start + '-' + this.index + ' [' + this.text.substring(start, end) + ']' :
                    ' ' + end);
                throw $parseMinErr('lexerr', 'Lexer Error: {0} at column{1} in expression [{2}].',
                    error, colStr, this.text);
            },
            readNumber: function() {
                var number = '';
                var start = this.index;
                while (this.index < this.text.length) {
                    var ch = lowercase(this.text.charAt(this.index));
                    if (ch == '.' || this.isNumber(ch)) {
                        number += ch;
                    } else {
                        var peekCh = this.peek();
                        if (ch == 'e' && this.isExpOperator(peekCh)) {
                            number += ch;
                        } else if (this.isExpOperator(ch) &&
                            peekCh && this.isNumber(peekCh) &&
                            number.charAt(number.length - 1) == 'e') {
                            number += ch;
                        } else if (this.isExpOperator(ch) &&
                            (!peekCh || !this.isNumber(peekCh)) &&
                            number.charAt(number.length - 1) == 'e') {
                            this.throwError('Invalid exponent');
                        } else {
                            break;
                        }
                    }
                    this.index++;
                }
                this.tokens.push({
                    index: start,
                    text: number,
                    constant: true,
                    value: Number(number)
                });
            },
            readIdent: function() {
                var start = this.index;
                while (this.index < this.text.length) {
                    var ch = this.text.charAt(this.index);
                    if (!(this.isIdent(ch) || this.isNumber(ch))) {
                        break;
                    }
                    this.index++;
                }
                this.tokens.push({
                    index: start,
                    text: this.text.slice(start, this.index),
                    identifier: true
                });
            },
            readString: function(quote) {
                var start = this.index;
                this.index++;
                var string = '';
                var rawString = quote;
                var escape = false;
                while (this.index < this.text.length) {
                    var ch = this.text.charAt(this.index);
                    rawString += ch;
                    if (escape) {
                        if (ch === 'u') {
                            var hex = this.text.substring(this.index + 1, this.index + 5);
                            if (!hex.match(/[\da-f]{4}/i)) {
                                this.throwError('Invalid unicode escape [\\u' + hex + ']');
                            }
                            this.index += 4;
                            string += String.fromCharCode(parseInt(hex, 16));
                        } else {
                            var rep = ESCAPE[ch];
                            string = string + (rep || ch);
                        }
                        escape = false;
                    } else if (ch === '\\') {
                        escape = true;
                    } else if (ch === quote) {
                        this.index++;
                        this.tokens.push({
                            index: start,
                            text: rawString,
                            constant: true,
                            value: string
                        });
                        return;
                    } else {
                        string += ch;
                    }
                    this.index++;
                }
                this.throwError('Unterminated quote', start);
            }
        };
        var AST = function(lexer, options) {
            this.lexer = lexer;
            this.options = options;
        };
        AST.Program = 'Program';
        AST.ExpressionStatement = 'ExpressionStatement';
        AST.AssignmentExpression = 'AssignmentExpression';
        AST.ConditionalExpression = 'ConditionalExpression';
        AST.LogicalExpression = 'LogicalExpression';
        AST.BinaryExpression = 'BinaryExpression';
        AST.UnaryExpression = 'UnaryExpression';
        AST.CallExpression = 'CallExpression';
        AST.MemberExpression = 'MemberExpression';
        AST.Identifier = 'Identifier';
        AST.Literal = 'Literal';
        AST.ArrayExpression = 'ArrayExpression';
        AST.Property = 'Property';
        AST.ObjectExpression = 'ObjectExpression';
        AST.ThisExpression = 'ThisExpression';
        AST.LocalsExpression = 'LocalsExpression';
        AST.NGValueParameter = 'NGValueParameter';
        AST.prototype = {
            ast: function(text) {
                this.text = text;
                this.tokens = this.lexer.lex(text);
                var value = this.program();
                if (this.tokens.length !== 0) {
                    this.throwError('is an unexpected token', this.tokens[0]);
                }
                return value;
            },
            program: function() {
                var body = [];
                while (true) {
                    if (this.tokens.length > 0 && !this.peek('}', ')', ';', ']'))
                        body.push(this.expressionStatement());
                    if (!this.expect(';')) {
                        return {
                            type: AST.Program,
                            body: body
                        };
                    }
                }
            },
            expressionStatement: function() {
                return {
                    type: AST.ExpressionStatement,
                    expression: this.filterChain()
                };
            },
            filterChain: function() {
                var left = this.expression();
                var token;
                while ((token = this.expect('|'))) {
                    left = this.filter(left);
                }
                return left;
            },
            expression: function() {
                return this.assignment();
            },
            assignment: function() {
                var result = this.ternary();
                if (this.expect('=')) {
                    result = {
                        type: AST.AssignmentExpression,
                        left: result,
                        right: this.assignment(),
                        operator: '='
                    };
                }
                return result;
            },
            ternary: function() {
                var test = this.logicalOR();
                var alternate;
                var consequent;
                if (this.expect('?')) {
                    alternate = this.expression();
                    if (this.consume(':')) {
                        consequent = this.expression();
                        return {
                            type: AST.ConditionalExpression,
                            test: test,
                            alternate: alternate,
                            consequent: consequent
                        };
                    }
                }
                return test;
            },
            logicalOR: function() {
                var left = this.logicalAND();
                while (this.expect('||')) {
                    left = {
                        type: AST.LogicalExpression,
                        operator: '||',
                        left: left,
                        right: this.logicalAND()
                    };
                }
                return left;
            },
            logicalAND: function() {
                var left = this.equality();
                while (this.expect('&&')) {
                    left = {
                        type: AST.LogicalExpression,
                        operator: '&&',
                        left: left,
                        right: this.equality()
                    };
                }
                return left;
            },
            equality: function() {
                var left = this.relational();
                var token;
                while ((token = this.expect('==', '!=', '===', '!=='))) {
                    left = {
                        type: AST.BinaryExpression,
                        operator: token.text,
                        left: left,
                        right: this.relational()
                    };
                }
                return left;
            },
            relational: function() {
                var left = this.additive();
                var token;
                while ((token = this.expect('<', '>', '<=', '>='))) {
                    left = {
                        type: AST.BinaryExpression,
                        operator: token.text,
                        left: left,
                        right: this.additive()
                    };
                }
                return left;
            },
            additive: function() {
                var left = this.multiplicative();
                var token;
                while ((token = this.expect('+', '-'))) {
                    left = {
                        type: AST.BinaryExpression,
                        operator: token.text,
                        left: left,
                        right: this.multiplicative()
                    };
                }
                return left;
            },
            multiplicative: function() {
                var left = this.unary();
                var token;
                while ((token = this.expect('*', '/', '%'))) {
                    left = {
                        type: AST.BinaryExpression,
                        operator: token.text,
                        left: left,
                        right: this.unary()
                    };
                }
                return left;
            },
            unary: function() {
                var token;
                if ((token = this.expect('+', '-', '!'))) {
                    return {
                        type: AST.UnaryExpression,
                        operator: token.text,
                        prefix: true,
                        argument: this.unary()
                    };
                } else {
                    return this.primary();
                }
            },
            primary: function() {
                var primary;
                if (this.expect('(')) {
                    primary = this.filterChain();
                    this.consume(')');
                } else if (this.expect('[')) {
                    primary = this.arrayDeclaration();
                } else if (this.expect('{')) {
                    primary = this.object();
                } else if (this.selfReferential.hasOwnProperty(this.peek().text)) {
                    primary = copy(this.selfReferential[this.consume().text]);
                } else if (this.options.literals.hasOwnProperty(this.peek().text)) {
                    primary = {
                        type: AST.Literal,
                        value: this.options.literals[this.consume().text]
                    };
                } else if (this.peek().identifier) {
                    primary = this.identifier();
                } else if (this.peek().constant) {
                    primary = this.constant();
                } else {
                    this.throwError('not a primary expression', this.peek());
                }
                var next;
                while ((next = this.expect('(', '[', '.'))) {
                    if (next.text === '(') {
                        primary = {
                            type: AST.CallExpression,
                            callee: primary,
                            arguments: this.parseArguments()
                        };
                        this.consume(')');
                    } else if (next.text === '[') {
                        primary = {
                            type: AST.MemberExpression,
                            object: primary,
                            property: this.expression(),
                            computed: true
                        };
                        this.consume(']');
                    } else if (next.text === '.') {
                        primary = {
                            type: AST.MemberExpression,
                            object: primary,
                            property: this.identifier(),
                            computed: false
                        };
                    } else {
                        this.throwError('IMPOSSIBLE');
                    }
                }
                return primary;
            },
            filter: function(baseExpression) {
                var args = [baseExpression];
                var result = {
                    type: AST.CallExpression,
                    callee: this.identifier(),
                    arguments: args,
                    filter: true
                };
                while (this.expect(':')) {
                    args.push(this.expression());
                }
                return result;
            },
            parseArguments: function() {
                var args = [];
                if (this.peekToken().text !== ')') {
                    do {
                        args.push(this.expression());
                    } while (this.expect(','));
                }
                return args;
            },
            identifier: function() {
                var token = this.consume();
                if (!token.identifier) {
                    this.throwError('is not a valid identifier', token);
                }
                return {
                    type: AST.Identifier,
                    name: token.text
                };
            },
            constant: function() {
                return {
                    type: AST.Literal,
                    value: this.consume().value
                };
            },
            arrayDeclaration: function() {
                var elements = [];
                if (this.peekToken().text !== ']') {
                    do {
                        if (this.peek(']')) {
                            break;
                        }
                        elements.push(this.expression());
                    } while (this.expect(','));
                }
                this.consume(']');
                return {
                    type: AST.ArrayExpression,
                    elements: elements
                };
            },
            object: function() {
                var properties = [],
                    property;
                if (this.peekToken().text !== '}') {
                    do {
                        if (this.peek('}')) {
                            break;
                        }
                        property = {
                            type: AST.Property,
                            kind: 'init'
                        };
                        if (this.peek().constant) {
                            property.key = this.constant();
                        } else if (this.peek().identifier) {
                            property.key = this.identifier();
                        } else {
                            this.throwError("invalid key", this.peek());
                        }
                        this.consume(':');
                        property.value = this.expression();
                        properties.push(property);
                    } while (this.expect(','));
                }
                this.consume('}');
                return {
                    type: AST.ObjectExpression,
                    properties: properties
                };
            },
            throwError: function(msg, token) {
                throw $parseMinErr('syntax',
                    'Syntax Error: Token \'{0}\' {1} at column {2} of the expression [{3}] starting at [{4}].',
                    token.text, msg, (token.index + 1), this.text, this.text.substring(token.index));
            },
            consume: function(e1) {
                if (this.tokens.length === 0) {
                    throw $parseMinErr('ueoe', 'Unexpected end of expression: {0}', this.text);
                }
                var token = this.expect(e1);
                if (!token) {
                    this.throwError('is unexpected, expecting [' + e1 + ']', this.peek());
                }
                return token;
            },
            peekToken: function() {
                if (this.tokens.length === 0) {
                    throw $parseMinErr('ueoe', 'Unexpected end of expression: {0}', this.text);
                }
                return this.tokens[0];
            },
            peek: function(e1, e2, e3, e4) {
                return this.peekAhead(0, e1, e2, e3, e4);
            },
            peekAhead: function(i, e1, e2, e3, e4) {
                if (this.tokens.length > i) {
                    var token = this.tokens[i];
                    var t = token.text;
                    if (t === e1 || t === e2 || t === e3 || t === e4 ||
                        (!e1 && !e2 && !e3 && !e4)) {
                        return token;
                    }
                }
                return false;
            },
            expect: function(e1, e2, e3, e4) {
                var token = this.peek(e1, e2, e3, e4);
                if (token) {
                    this.tokens.shift();
                    return token;
                }
                return false;
            },
            selfReferential: {
                'this': {
                    type: AST.ThisExpression
                },
                '$locals': {
                    type: AST.LocalsExpression
                }
            }
        };
    
        function ifDefined(v, d) {
            return typeof v !== 'undefined' ? v : d;
        }
    
        function plusFn(l, r) {
            if (typeof l === 'undefined') return r;
            if (typeof r === 'undefined') return l;
            return l + r;
        }
    
        function isStateless($filter, filterName) {
            var fn = $filter(filterName);
            return !fn.$stateful;
        }
    
        function findConstantAndWatchExpressions(ast, $filter) {
            var allConstants;
            var argsToWatch;
            switch (ast.type) {
                case AST.Program:
                    allConstants = true;
                    forEach(ast.body, function(expr) {
                        findConstantAndWatchExpressions(expr.expression, $filter);
                        allConstants = allConstants && expr.expression.constant;
                    });
                    ast.constant = allConstants;
                    break;
                case AST.Literal:
                    ast.constant = true;
                    ast.toWatch = [];
                    break;
                case AST.UnaryExpression:
                    findConstantAndWatchExpressions(ast.argument, $filter);
                    ast.constant = ast.argument.constant;
                    ast.toWatch = ast.argument.toWatch;
                    break;
                case AST.BinaryExpression:
                    findConstantAndWatchExpressions(ast.left, $filter);
                    findConstantAndWatchExpressions(ast.right, $filter);
                    ast.constant = ast.left.constant && ast.right.constant;
                    ast.toWatch = ast.left.toWatch.concat(ast.right.toWatch);
                    break;
                case AST.LogicalExpression:
                    findConstantAndWatchExpressions(ast.left, $filter);
                    findConstantAndWatchExpressions(ast.right, $filter);
                    ast.constant = ast.left.constant && ast.right.constant;
                    ast.toWatch = ast.constant ? [] : [ast];
                    break;
                case AST.ConditionalExpression:
                    findConstantAndWatchExpressions(ast.test, $filter);
                    findConstantAndWatchExpressions(ast.alternate, $filter);
                    findConstantAndWatchExpressions(ast.consequent, $filter);
                    ast.constant = ast.test.constant && ast.alternate.constant && ast.consequent.constant;
                    ast.toWatch = ast.constant ? [] : [ast];
                    break;
                case AST.Identifier:
                    ast.constant = false;
                    ast.toWatch = [ast];
                    break;
                case AST.MemberExpression:
                    findConstantAndWatchExpressions(ast.object, $filter);
                    if (ast.computed) {
                        findConstantAndWatchExpressions(ast.property, $filter);
                    }
                    ast.constant = ast.object.constant && (!ast.computed || ast.property.constant);
                    ast.toWatch = [ast];
                    break;
                case AST.CallExpression:
                    allConstants = ast.filter ? isStateless($filter, ast.callee.name) : false;
                    argsToWatch = [];
                    forEach(ast.arguments, function(expr) {
                        findConstantAndWatchExpressions(expr, $filter);
                        allConstants = allConstants && expr.constant;
                        if (!expr.constant) {
                            argsToWatch.push.apply(argsToWatch, expr.toWatch);
                        }
                    });
                    ast.constant = allConstants;
                    ast.toWatch = ast.filter && isStateless($filter, ast.callee.name) ? argsToWatch : [ast];
                    break;
                case AST.AssignmentExpression:
                    findConstantAndWatchExpressions(ast.left, $filter);
                    findConstantAndWatchExpressions(ast.right, $filter);
                    ast.constant = ast.left.constant && ast.right.constant;
                    ast.toWatch = [ast];
                    break;
                case AST.ArrayExpression:
                    allConstants = true;
                    argsToWatch = [];
                    forEach(ast.elements, function(expr) {
                        findConstantAndWatchExpressions(expr, $filter);
                        allConstants = allConstants && expr.constant;
                        if (!expr.constant) {
                            argsToWatch.push.apply(argsToWatch, expr.toWatch);
                        }
                    });
                    ast.constant = allConstants;
                    ast.toWatch = argsToWatch;
                    break;
                case AST.ObjectExpression:
                    allConstants = true;
                    argsToWatch = [];
                    forEach(ast.properties, function(property) {
                        findConstantAndWatchExpressions(property.value, $filter);
                        allConstants = allConstants && property.value.constant;
                        if (!property.value.constant) {
                            argsToWatch.push.apply(argsToWatch, property.value.toWatch);
                        }
                    });
                    ast.constant = allConstants;
                    ast.toWatch = argsToWatch;
                    break;
                case AST.ThisExpression:
                    ast.constant = false;
                    ast.toWatch = [];
                    break;
                case AST.LocalsExpression:
                    ast.constant = false;
                    ast.toWatch = [];
                    break;
            }
        }
    
        function getInputs(body) {
            if (body.length != 1) return;
            var lastExpression = body[0].expression;
            var candidate = lastExpression.toWatch;
            if (candidate.length !== 1) return candidate;
            return candidate[0] !== lastExpression ? candidate : undefined;
        }
    
        function isAssignable(ast) {
            return ast.type === AST.Identifier || ast.type === AST.MemberExpression;
        }
    
        function assignableAST(ast) {
            if (ast.body.length === 1 && isAssignable(ast.body[0].expression)) {
                return {
                    type: AST.AssignmentExpression,
                    left: ast.body[0].expression,
                    right: {
                        type: AST.NGValueParameter
                    },
                    operator: '='
                };
            }
        }
    
        function isLiteral(ast) {
            return ast.body.length === 0 ||
                ast.body.length === 1 && (
                    ast.body[0].expression.type === AST.Literal ||
                    ast.body[0].expression.type === AST.ArrayExpression ||
                    ast.body[0].expression.type === AST.ObjectExpression);
        }
    
        function isConstant(ast) {
            return ast.constant;
        }
    
        function ASTCompiler(astBuilder, $filter) {
            this.astBuilder = astBuilder;
            this.$filter = $filter;
        }
        ASTCompiler.prototype = {
            compile: function(expression, expensiveChecks) {
                var self = this;
                var ast = this.astBuilder.ast(expression);
                this.state = {
                    nextId: 0,
                    filters: {},
                    expensiveChecks: expensiveChecks,
                    fn: {
                        vars: [],
                        body: [],
                        own: {}
                    },
                    assign: {
                        vars: [],
                        body: [],
                        own: {}
                    },
                    inputs: []
                };
                findConstantAndWatchExpressions(ast, self.$filter);
                var extra = '';
                var assignable;
                this.stage = 'assign';
                if ((assignable = assignableAST(ast))) {
                    this.state.computing = 'assign';
                    var result = this.nextId();
                    this.recurse(assignable, result);
                    this.return_(result);
                    extra = 'fn.assign=' + this.generateFunction('assign', 's,v,l');
                }
                var toWatch = getInputs(ast.body);
                self.stage = 'inputs';
                forEach(toWatch, function(watch, key) {
                    var fnKey = 'fn' + key;
                    self.state[fnKey] = {
                        vars: [],
                        body: [],
                        own: {}
                    };
                    self.state.computing = fnKey;
                    var intoId = self.nextId();
                    self.recurse(watch, intoId);
                    self.return_(intoId);
                    self.state.inputs.push(fnKey);
                    watch.watchId = key;
                });
                this.state.computing = 'fn';
                this.stage = 'main';
                this.recurse(ast);
                var fnString =
                    '"' + this.USE + ' ' + this.STRICT + '";\n' +
                    this.filterPrefix() +
                    'var fn=' + this.generateFunction('fn', 's,l,a,i') +
                    extra +
                    this.watchFns() +
                    'return fn;';
                var fn = (new Function('$filter',
                    'ensureSafeMemberName',
                    'ensureSafeObject',
                    'ensureSafeFunction',
                    'getStringValue',
                    'ensureSafeAssignContext',
                    'ifDefined',
                    'plus',
                    'text',
                    fnString))(
                    this.$filter,
                    ensureSafeMemberName,
                    ensureSafeObject,
                    ensureSafeFunction,
                    getStringValue,
                    ensureSafeAssignContext,
                    ifDefined,
                    plusFn,
                    expression);
                this.state = this.stage = undefined;
                fn.literal = isLiteral(ast);
                fn.constant = isConstant(ast);
                return fn;
            },
            USE: 'use',
            STRICT: 'strict',
            watchFns: function() {
                var result = [];
                var fns = this.state.inputs;
                var self = this;
                forEach(fns, function(name) {
                    result.push('var ' + name + '=' + self.generateFunction(name, 's'));
                });
                if (fns.length) {
                    result.push('fn.inputs=[' + fns.join(',') + '];');
                }
                return result.join('');
            },
            generateFunction: function(name, params) {
                return 'function(' + params + '){' +
                    this.varsPrefix(name) +
                    this.body(name) +
                    '};';
            },
            filterPrefix: function() {
                var parts = [];
                var self = this;
                forEach(this.state.filters, function(id, filter) {
                    parts.push(id + '=$filter(' + self.escape(filter) + ')');
                });
                if (parts.length) return 'var ' + parts.join(',') + ';';
                return '';
            },
            varsPrefix: function(section) {
                return this.state[section].vars.length ? 'var ' + this.state[section].vars.join(',') + ';' : '';
            },
            body: function(section) {
                return this.state[section].body.join('');
            },
            recurse: function(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck) {
                var left, right, self = this,
                    args, expression;
                recursionFn = recursionFn || noop;
                if (!skipWatchIdCheck && isDefined(ast.watchId)) {
                    intoId = intoId || this.nextId();
                    this.if_('i',
                        this.lazyAssign(intoId, this.computedMember('i', ast.watchId)),
                        this.lazyRecurse(ast, intoId, nameId, recursionFn, create, true)
                    );
                    return;
                }
                switch (ast.type) {
                    case AST.Program:
                        forEach(ast.body, function(expression, pos) {
                            self.recurse(expression.expression, undefined, undefined, function(expr) {
                                right = expr;
                            });
                            if (pos !== ast.body.length - 1) {
                                self.current().body.push(right, ';');
                            } else {
                                self.return_(right);
                            }
                        });
                        break;
                    case AST.Literal:
                        expression = this.escape(ast.value);
                        this.assign(intoId, expression);
                        recursionFn(expression);
                        break;
                    case AST.UnaryExpression:
                        this.recurse(ast.argument, undefined, undefined, function(expr) {
                            right = expr;
                        });
                        expression = ast.operator + '(' + this.ifDefined(right, 0) + ')';
                        this.assign(intoId, expression);
                        recursionFn(expression);
                        break;
                    case AST.BinaryExpression:
                        this.recurse(ast.left, undefined, undefined, function(expr) {
                            left = expr;
                        });
                        this.recurse(ast.right, undefined, undefined, function(expr) {
                            right = expr;
                        });
                        if (ast.operator === '+') {
                            expression = this.plus(left, right);
                        } else if (ast.operator === '-') {
                            expression = this.ifDefined(left, 0) + ast.operator + this.ifDefined(right, 0);
                        } else {
                            expression = '(' + left + ')' + ast.operator + '(' + right + ')';
                        }
                        this.assign(intoId, expression);
                        recursionFn(expression);
                        break;
                    case AST.LogicalExpression:
                        intoId = intoId || this.nextId();
                        self.recurse(ast.left, intoId);
                        self.if_(ast.operator === '&&' ? intoId : self.not(intoId), self.lazyRecurse(ast.right, intoId));
                        recursionFn(intoId);
                        break;
                    case AST.ConditionalExpression:
                        intoId = intoId || this.nextId();
                        self.recurse(ast.test, intoId);
                        self.if_(intoId, self.lazyRecurse(ast.alternate, intoId), self.lazyRecurse(ast.consequent, intoId));
                        recursionFn(intoId);
                        break;
                    case AST.Identifier:
                        intoId = intoId || this.nextId();
                        if (nameId) {
                            nameId.context = self.stage === 'inputs' ? 's' : this.assign(this.nextId(), this.getHasOwnProperty('l', ast.name) + '?l:s');
                            nameId.computed = false;
                            nameId.name = ast.name;
                        }
                        ensureSafeMemberName(ast.name);
                        self.if_(self.stage === 'inputs' || self.not(self.getHasOwnProperty('l', ast.name)),
                            function() {
                                self.if_(self.stage === 'inputs' || 's', function() {
                                    if (create && create !== 1) {
                                        self.if_(
                                            self.not(self.nonComputedMember('s', ast.name)),
                                            self.lazyAssign(self.nonComputedMember('s', ast.name), '{}'));
                                    }
                                    self.assign(intoId, self.nonComputedMember('s', ast.name));
                                });
                            }, intoId && self.lazyAssign(intoId, self.nonComputedMember('l', ast.name))
                        );
                        if (self.state.expensiveChecks || isPossiblyDangerousMemberName(ast.name)) {
                            self.addEnsureSafeObject(intoId);
                        }
                        recursionFn(intoId);
                        break;
                    case AST.MemberExpression:
                        left = nameId && (nameId.context = this.nextId()) || this.nextId();
                        intoId = intoId || this.nextId();
                        self.recurse(ast.object, left, undefined, function() {
                            self.if_(self.notNull(left), function() {
                                if (create && create !== 1) {
                                    self.addEnsureSafeAssignContext(left);
                                }
                                if (ast.computed) {
                                    right = self.nextId();
                                    self.recurse(ast.property, right);
                                    self.getStringValue(right);
                                    self.addEnsureSafeMemberName(right);
                                    if (create && create !== 1) {
                                        self.if_(self.not(self.computedMember(left, right)), self.lazyAssign(self.computedMember(left, right), '{}'));
                                    }
                                    expression = self.ensureSafeObject(self.computedMember(left, right));
                                    self.assign(intoId, expression);
                                    if (nameId) {
                                        nameId.computed = true;
                                        nameId.name = right;
                                    }
                                } else {
                                    ensureSafeMemberName(ast.property.name);
                                    if (create && create !== 1) {
                                        self.if_(self.not(self.nonComputedMember(left, ast.property.name)), self.lazyAssign(self.nonComputedMember(left, ast.property.name), '{}'));
                                    }
                                    expression = self.nonComputedMember(left, ast.property.name);
                                    if (self.state.expensiveChecks || isPossiblyDangerousMemberName(ast.property.name)) {
                                        expression = self.ensureSafeObject(expression);
                                    }
                                    self.assign(intoId, expression);
                                    if (nameId) {
                                        nameId.computed = false;
                                        nameId.name = ast.property.name;
                                    }
                                }
                            }, function() {
                                self.assign(intoId, 'undefined');
                            });
                            recursionFn(intoId);
                        }, !!create);
                        break;
                    case AST.CallExpression:
                        intoId = intoId || this.nextId();
                        if (ast.filter) {
                            right = self.filter(ast.callee.name);
                            args = [];
                            forEach(ast.arguments, function(expr) {
                                var argument = self.nextId();
                                self.recurse(expr, argument);
                                args.push(argument);
                            });
                            expression = right + '(' + args.join(',') + ')';
                            self.assign(intoId, expression);
                            recursionFn(intoId);
                        } else {
                            right = self.nextId();
                            left = {};
                            args = [];
                            self.recurse(ast.callee, right, left, function() {
                                self.if_(self.notNull(right), function() {
                                    self.addEnsureSafeFunction(right);
                                    forEach(ast.arguments, function(expr) {
                                        self.recurse(expr, self.nextId(), undefined, function(argument) {
                                            args.push(self.ensureSafeObject(argument));
                                        });
                                    });
                                    if (left.name) {
                                        if (!self.state.expensiveChecks) {
                                            self.addEnsureSafeObject(left.context);
                                        }
                                        expression = self.member(left.context, left.name, left.computed) + '(' + args.join(',') + ')';
                                    } else {
                                        expression = right + '(' + args.join(',') + ')';
                                    }
                                    expression = self.ensureSafeObject(expression);
                                    self.assign(intoId, expression);
                                }, function() {
                                    self.assign(intoId, 'undefined');
                                });
                                recursionFn(intoId);
                            });
                        }
                        break;
                    case AST.AssignmentExpression:
                        right = this.nextId();
                        left = {};
                        if (!isAssignable(ast.left)) {
                            throw $parseMinErr('lval', 'Trying to assign a value to a non l-value');
                        }
                        this.recurse(ast.left, undefined, left, function() {
                            self.if_(self.notNull(left.context), function() {
                                self.recurse(ast.right, right);
                                self.addEnsureSafeObject(self.member(left.context, left.name, left.computed));
                                self.addEnsureSafeAssignContext(left.context);
                                expression = self.member(left.context, left.name, left.computed) + ast.operator + right;
                                self.assign(intoId, expression);
                                recursionFn(intoId || expression);
                            });
                        }, 1);
                        break;
                    case AST.ArrayExpression:
                        args = [];
                        forEach(ast.elements, function(expr) {
                            self.recurse(expr, self.nextId(), undefined, function(argument) {
                                args.push(argument);
                            });
                        });
                        expression = '[' + args.join(',') + ']';
                        this.assign(intoId, expression);
                        recursionFn(expression);
                        break;
                    case AST.ObjectExpression:
                        args = [];
                        forEach(ast.properties, function(property) {
                            self.recurse(property.value, self.nextId(), undefined, function(expr) {
                                args.push(self.escape(
                                        property.key.type === AST.Identifier ? property.key.name :
                                        ('' + property.key.value)) +
                                    ':' + expr);
                            });
                        });
                        expression = '{' + args.join(',') + '}';
                        this.assign(intoId, expression);
                        recursionFn(expression);
                        break;
                    case AST.ThisExpression:
                        this.assign(intoId, 's');
                        recursionFn('s');
                        break;
                    case AST.LocalsExpression:
                        this.assign(intoId, 'l');
                        recursionFn('l');
                        break;
                    case AST.NGValueParameter:
                        this.assign(intoId, 'v');
                        recursionFn('v');
                        break;
                }
            },
            getHasOwnProperty: function(element, property) {
                var key = element + '.' + property;
                var own = this.current().own;
                if (!own.hasOwnProperty(key)) {
                    own[key] = this.nextId(false, element + '&&(' + this.escape(property) + ' in ' + element + ')');
                }
                return own[key];
            },
            assign: function(id, value) {
                if (!id) return;
                this.current().body.push(id, '=', value, ';');
                return id;
            },
            filter: function(filterName) {
                if (!this.state.filters.hasOwnProperty(filterName)) {
                    this.state.filters[filterName] = this.nextId(true);
                }
                return this.state.filters[filterName];
            },
            ifDefined: function(id, defaultValue) {
                return 'ifDefined(' + id + ',' + this.escape(defaultValue) + ')';
            },
            plus: function(left, right) {
                return 'plus(' + left + ',' + right + ')';
            },
            return_: function(id) {
                this.current().body.push('return ', id, ';');
            },
            if_: function(test, alternate, consequent) {
                if (test === true) {
                    alternate();
                } else {
                    var body = this.current().body;
                    body.push('if(', test, '){');
                    alternate();
                    body.push('}');
                    if (consequent) {
                        body.push('else{');
                        consequent();
                        body.push('}');
                    }
                }
            },
            not: function(expression) {
                return '!(' + expression + ')';
            },
            notNull: function(expression) {
                return expression + '!=null';
            },
            nonComputedMember: function(left, right) {
                return left + '.' + right;
            },
            computedMember: function(left, right) {
                return left + '[' + right + ']';
            },
            member: function(left, right, computed) {
                if (computed) return this.computedMember(left, right);
                return this.nonComputedMember(left, right);
            },
            addEnsureSafeObject: function(item) {
                this.current().body.push(this.ensureSafeObject(item), ';');
            },
            addEnsureSafeMemberName: function(item) {
                this.current().body.push(this.ensureSafeMemberName(item), ';');
            },
            addEnsureSafeFunction: function(item) {
                this.current().body.push(this.ensureSafeFunction(item), ';');
            },
            addEnsureSafeAssignContext: function(item) {
                this.current().body.push(this.ensureSafeAssignContext(item), ';');
            },
            ensureSafeObject: function(item) {
                return 'ensureSafeObject(' + item + ',text)';
            },
            ensureSafeMemberName: function(item) {
                return 'ensureSafeMemberName(' + item + ',text)';
            },
            ensureSafeFunction: function(item) {
                return 'ensureSafeFunction(' + item + ',text)';
            },
            getStringValue: function(item) {
                this.assign(item, 'getStringValue(' + item + ')');
            },
            ensureSafeAssignContext: function(item) {
                return 'ensureSafeAssignContext(' + item + ',text)';
            },
            lazyRecurse: function(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck) {
                var self = this;
                return function() {
                    self.recurse(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck);
                };
            },
            lazyAssign: function(id, value) {
                var self = this;
                return function() {
                    self.assign(id, value);
                };
            },
            stringEscapeRegex: /[^ a-zA-Z0-9]/g,
            stringEscapeFn: function(c) {
                return '\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4);
            },
            escape: function(value) {
                if (isString(value)) return "'" + value.replace(this.stringEscapeRegex, this.stringEscapeFn) + "'";
                if (isNumber(value)) return value.toString();
                if (value === true) return 'true';
                if (value === false) return 'false';
                if (value === null) return 'null';
                if (typeof value === 'undefined') return 'undefined';
                throw $parseMinErr('esc', 'IMPOSSIBLE');
            },
            nextId: function(skip, init) {
                var id = 'v' + (this.state.nextId++);
                if (!skip) {
                    this.current().vars.push(id + (init ? '=' + init : ''));
                }
                return id;
            },
            current: function() {
                return this.state[this.state.computing];
            }
        };
    
        function ASTInterpreter(astBuilder, $filter) {
            this.astBuilder = astBuilder;
            this.$filter = $filter;
        }
        ASTInterpreter.prototype = {
            compile: function(expression, expensiveChecks) {
                var self = this;
                var ast = this.astBuilder.ast(expression);
                this.expression = expression;
                this.expensiveChecks = expensiveChecks;
                findConstantAndWatchExpressions(ast, self.$filter);
                var assignable;
                var assign;
                if ((assignable = assignableAST(ast))) {
                    assign = this.recurse(assignable);
                }
                var toWatch = getInputs(ast.body);
                var inputs;
                if (toWatch) {
                    inputs = [];
                    forEach(toWatch, function(watch, key) {
                        var input = self.recurse(watch);
                        watch.input = input;
                        inputs.push(input);
                        watch.watchId = key;
                    });
                }
                var expressions = [];
                forEach(ast.body, function(expression) {
                    expressions.push(self.recurse(expression.expression));
                });
                var fn = ast.body.length === 0 ? noop :
                    ast.body.length === 1 ? expressions[0] :
                    function(scope, locals) {
                        var lastValue;
                        forEach(expressions, function(exp) {
                            lastValue = exp(scope, locals);
                        });
                        return lastValue;
                    };
                if (assign) {
                    fn.assign = function(scope, value, locals) {
                        return assign(scope, locals, value);
                    };
                }
                if (inputs) {
                    fn.inputs = inputs;
                }
                fn.literal = isLiteral(ast);
                fn.constant = isConstant(ast);
                return fn;
            },
            recurse: function(ast, context, create) {
                var left, right, self = this,
                    args, expression;
                if (ast.input) {
                    return this.inputs(ast.input, ast.watchId);
                }
                switch (ast.type) {
                    case AST.Literal:
                        return this.value(ast.value, context);
                    case AST.UnaryExpression:
                        right = this.recurse(ast.argument);
                        return this['unary' + ast.operator](right, context);
                    case AST.BinaryExpression:
                        left = this.recurse(ast.left);
                        right = this.recurse(ast.right);
                        return this['binary' + ast.operator](left, right, context);
                    case AST.LogicalExpression:
                        left = this.recurse(ast.left);
                        right = this.recurse(ast.right);
                        return this['binary' + ast.operator](left, right, context);
                    case AST.ConditionalExpression:
                        return this['ternary?:'](
                            this.recurse(ast.test),
                            this.recurse(ast.alternate),
                            this.recurse(ast.consequent),
                            context
                        );
                    case AST.Identifier:
                        ensureSafeMemberName(ast.name, self.expression);
                        return self.identifier(ast.name,
                            self.expensiveChecks || isPossiblyDangerousMemberName(ast.name),
                            context, create, self.expression);
                    case AST.MemberExpression:
                        left = this.recurse(ast.object, false, !!create);
                        if (!ast.computed) {
                            ensureSafeMemberName(ast.property.name, self.expression);
                            right = ast.property.name;
                        }
                        if (ast.computed) right = this.recurse(ast.property);
                        return ast.computed ?
                            this.computedMember(left, right, context, create, self.expression) :
                            this.nonComputedMember(left, right, self.expensiveChecks, context, create, self.expression);
                    case AST.CallExpression:
                        args = [];
                        forEach(ast.arguments, function(expr) {
                            args.push(self.recurse(expr));
                        });
                        if (ast.filter) right = this.$filter(ast.callee.name);
                        if (!ast.filter) right = this.recurse(ast.callee, true);
                        return ast.filter ?
                            function(scope, locals, assign, inputs) {
                                var values = [];
                                for (var i = 0; i < args.length; ++i) {
                                    values.push(args[i](scope, locals, assign, inputs));
                                }
                                var value = right.apply(undefined, values, inputs);
                                return context ? {
                                    context: undefined,
                                    name: undefined,
                                    value: value
                                } : value;
                            } :
                            function(scope, locals, assign, inputs) {
                                var rhs = right(scope, locals, assign, inputs);
                                var value;
                                if (rhs.value != null) {
                                    ensureSafeObject(rhs.context, self.expression);
                                    ensureSafeFunction(rhs.value, self.expression);
                                    var values = [];
                                    for (var i = 0; i < args.length; ++i) {
                                        values.push(ensureSafeObject(args[i](scope, locals, assign, inputs), self.expression));
                                    }
                                    value = ensureSafeObject(rhs.value.apply(rhs.context, values), self.expression);
                                }
                                return context ? {
                                    value: value
                                } : value;
                            };
                    case AST.AssignmentExpression:
                        left = this.recurse(ast.left, true, 1);
                        right = this.recurse(ast.right);
                        return function(scope, locals, assign, inputs) {
                            var lhs = left(scope, locals, assign, inputs);
                            var rhs = right(scope, locals, assign, inputs);
                            ensureSafeObject(lhs.value, self.expression);
                            ensureSafeAssignContext(lhs.context);
                            lhs.context[lhs.name] = rhs;
                            return context ? {
                                value: rhs
                            } : rhs;
                        };
                    case AST.ArrayExpression:
                        args = [];
                        forEach(ast.elements, function(expr) {
                            args.push(self.recurse(expr));
                        });
                        return function(scope, locals, assign, inputs) {
                            var value = [];
                            for (var i = 0; i < args.length; ++i) {
                                value.push(args[i](scope, locals, assign, inputs));
                            }
                            return context ? {
                                value: value
                            } : value;
                        };
                    case AST.ObjectExpression:
                        args = [];
                        forEach(ast.properties, function(property) {
                            args.push({
                                key: property.key.type === AST.Identifier ?
                                    property.key.name :
                                    ('' + property.key.value),
                                value: self.recurse(property.value)
                            });
                        });
                        return function(scope, locals, assign, inputs) {
                            var value = {};
                            for (var i = 0; i < args.length; ++i) {
                                value[args[i].key] = args[i].value(scope, locals, assign, inputs);
                            }
                            return context ? {
                                value: value
                            } : value;
                        };
                    case AST.ThisExpression:
                        return function(scope) {
                            return context ? {
                                value: scope
                            } : scope;
                        };
                    case AST.LocalsExpression:
                        return function(scope, locals) {
                            return context ? {
                                value: locals
                            } : locals;
                        };
                    case AST.NGValueParameter:
                        return function(scope, locals, assign) {
                            return context ? {
                                value: assign
                            } : assign;
                        };
                }
            },
            'unary+': function(argument, context) {
                return function(scope, locals, assign, inputs) {
                    var arg = argument(scope, locals, assign, inputs);
                    if (isDefined(arg)) {
                        arg = +arg;
                    } else {
                        arg = 0;
                    }
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'unary-': function(argument, context) {
                return function(scope, locals, assign, inputs) {
                    var arg = argument(scope, locals, assign, inputs);
                    if (isDefined(arg)) {
                        arg = -arg;
                    } else {
                        arg = 0;
                    }
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'unary!': function(argument, context) {
                return function(scope, locals, assign, inputs) {
                    var arg = !argument(scope, locals, assign, inputs);
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'binary+': function(left, right, context) {
                return function(scope, locals, assign, inputs) {
                    var lhs = left(scope, locals, assign, inputs);
                    var rhs = right(scope, locals, assign, inputs);
                    var arg = plusFn(lhs, rhs);
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'binary-': function(left, right, context) {
                return function(scope, locals, assign, inputs) {
                    var lhs = left(scope, locals, assign, inputs);
                    var rhs = right(scope, locals, assign, inputs);
                    var arg = (isDefined(lhs) ? lhs : 0) - (isDefined(rhs) ? rhs : 0);
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'binary*': function(left, right, context) {
                return function(scope, locals, assign, inputs) {
                    var arg = left(scope, locals, assign, inputs) * right(scope, locals, assign, inputs);
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'binary/': function(left, right, context) {
                return function(scope, locals, assign, inputs) {
                    var arg = left(scope, locals, assign, inputs) / right(scope, locals, assign, inputs);
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'binary%': function(left, right, context) {
                return function(scope, locals, assign, inputs) {
                    var arg = left(scope, locals, assign, inputs) % right(scope, locals, assign, inputs);
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'binary===': function(left, right, context) {
                return function(scope, locals, assign, inputs) {
                    var arg = left(scope, locals, assign, inputs) === right(scope, locals, assign, inputs);
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'binary!==': function(left, right, context) {
                return function(scope, locals, assign, inputs) {
                    var arg = left(scope, locals, assign, inputs) !== right(scope, locals, assign, inputs);
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'binary==': function(left, right, context) {
                return function(scope, locals, assign, inputs) {
                    var arg = left(scope, locals, assign, inputs) == right(scope, locals, assign, inputs);
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'binary!=': function(left, right, context) {
                return function(scope, locals, assign, inputs) {
                    var arg = left(scope, locals, assign, inputs) != right(scope, locals, assign, inputs);
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'binary<': function(left, right, context) {
                return function(scope, locals, assign, inputs) {
                    var arg = left(scope, locals, assign, inputs) < right(scope, locals, assign, inputs);
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'binary>': function(left, right, context) {
                return function(scope, locals, assign, inputs) {
                    var arg = left(scope, locals, assign, inputs) > right(scope, locals, assign, inputs);
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'binary<=': function(left, right, context) {
                return function(scope, locals, assign, inputs) {
                    var arg = left(scope, locals, assign, inputs) <= right(scope, locals, assign, inputs);
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'binary>=': function(left, right, context) {
                return function(scope, locals, assign, inputs) {
                    var arg = left(scope, locals, assign, inputs) >= right(scope, locals, assign, inputs);
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'binary&&': function(left, right, context) {
                return function(scope, locals, assign, inputs) {
                    var arg = left(scope, locals, assign, inputs) && right(scope, locals, assign, inputs);
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'binary||': function(left, right, context) {
                return function(scope, locals, assign, inputs) {
                    var arg = left(scope, locals, assign, inputs) || right(scope, locals, assign, inputs);
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            'ternary?:': function(test, alternate, consequent, context) {
                return function(scope, locals, assign, inputs) {
                    var arg = test(scope, locals, assign, inputs) ? alternate(scope, locals, assign, inputs) : consequent(scope, locals, assign, inputs);
                    return context ? {
                        value: arg
                    } : arg;
                };
            },
            value: function(value, context) {
                return function() {
                    return context ? {
                        context: undefined,
                        name: undefined,
                        value: value
                    } : value;
                };
            },
            identifier: function(name, expensiveChecks, context, create, expression) {
                return function(scope, locals, assign, inputs) {
                    var base = locals && (name in locals) ? locals : scope;
                    if (create && create !== 1 && base && !(base[name])) {
                        base[name] = {};
                    }
                    var value = base ? base[name] : undefined;
                    if (expensiveChecks) {
                        ensureSafeObject(value, expression);
                    }
                    if (context) {
                        return {
                            context: base,
                            name: name,
                            value: value
                        };
                    } else {
                        return value;
                    }
                };
            },
            computedMember: function(left, right, context, create, expression) {
                return function(scope, locals, assign, inputs) {
                    var lhs = left(scope, locals, assign, inputs);
                    var rhs;
                    var value;
                    if (lhs != null) {
                        rhs = right(scope, locals, assign, inputs);
                        rhs = getStringValue(rhs);
                        ensureSafeMemberName(rhs, expression);
                        if (create && create !== 1) {
                            ensureSafeAssignContext(lhs);
                            if (lhs && !(lhs[rhs])) {
                                lhs[rhs] = {};
                            }
                        }
                        value = lhs[rhs];
                        ensureSafeObject(value, expression);
                    }
                    if (context) {
                        return {
                            context: lhs,
                            name: rhs,
                            value: value
                        };
                    } else {
                        return value;
                    }
                };
            },
            nonComputedMember: function(left, right, expensiveChecks, context, create, expression) {
                return function(scope, locals, assign, inputs) {
                    var lhs = left(scope, locals, assign, inputs);
                    if (create && create !== 1) {
                        ensureSafeAssignContext(lhs);
                        if (lhs && !(lhs[right])) {
                            lhs[right] = {};
                        }
                    }
                    var value = lhs != null ? lhs[right] : undefined;
                    if (expensiveChecks || isPossiblyDangerousMemberName(right)) {
                        ensureSafeObject(value, expression);
                    }
                    if (context) {
                        return {
                            context: lhs,
                            name: right,
                            value: value
                        };
                    } else {
                        return value;
                    }
                };
            },
            inputs: function(input, watchId) {
                return function(scope, value, locals, inputs) {
                    if (inputs) return inputs[watchId];
                    return input(scope, value, locals);
                };
            }
        };
        var Parser = function(lexer, $filter, options) {
            this.lexer = lexer;
            this.$filter = $filter;
            this.options = options;
            this.ast = new AST(lexer, options);
            this.astCompiler = options.csp ? new ASTInterpreter(this.ast, $filter) :
                new ASTCompiler(this.ast, $filter);
        };
        Parser.prototype = {
            constructor: Parser,
            parse: function(text) {
                return this.astCompiler.compile(text, this.options.expensiveChecks);
            }
        };
    
        function isPossiblyDangerousMemberName(name) {
            return name == 'constructor';
        }
        var objectValueOf = Object.prototype.valueOf;
    
        function getValueOf(value) {
            return isFunction(value.valueOf) ? value.valueOf() : objectValueOf.call(value);
        }
    
        function $ParseProvider() {
            var cacheDefault = createMap();
            var cacheExpensive = createMap();
            var literals = {
                'true': true,
                'false': false,
                'null': null,
                'undefined': undefined
            };
            this.addLiteral = function(literalName, literalValue) {
                literals[literalName] = literalValue;
            };
            this.$get = ['$filter', function($filter) {
                var noUnsafeEval = csp().noUnsafeEval;
                var $parseOptions = {
                        csp: noUnsafeEval,
                        expensiveChecks: false,
                        literals: copy(literals)
                    },
                    $parseOptionsExpensive = {
                        csp: noUnsafeEval,
                        expensiveChecks: true,
                        literals: copy(literals)
                    };
                var runningChecksEnabled = false;
                $parse.$$runningExpensiveChecks = function() {
                    return runningChecksEnabled;
                };
                return $parse;
    
                function $parse(exp, interceptorFn, expensiveChecks) {
                    var parsedExpression, oneTime, cacheKey;
                    expensiveChecks = expensiveChecks || runningChecksEnabled;
                    switch (typeof exp) {
                        case 'string':
                            exp = exp.trim();
                            cacheKey = exp;
                            var cache = (expensiveChecks ? cacheExpensive : cacheDefault);
                            parsedExpression = cache[cacheKey];
                            if (!parsedExpression) {
                                if (exp.charAt(0) === ':' && exp.charAt(1) === ':') {
                                    oneTime = true;
                                    exp = exp.substring(2);
                                }
                                var parseOptions = expensiveChecks ? $parseOptionsExpensive : $parseOptions;
                                var lexer = new Lexer(parseOptions);
                                var parser = new Parser(lexer, $filter, parseOptions);
                                parsedExpression = parser.parse(exp);
                                if (parsedExpression.constant) {
                                    parsedExpression.$$watchDelegate = constantWatchDelegate;
                                } else if (oneTime) {
                                    parsedExpression.$$watchDelegate = parsedExpression.literal ?
                                        oneTimeLiteralWatchDelegate : oneTimeWatchDelegate;
                                } else if (parsedExpression.inputs) {
                                    parsedExpression.$$watchDelegate = inputsWatchDelegate;
                                }
                                if (expensiveChecks) {
                                    parsedExpression = expensiveChecksInterceptor(parsedExpression);
                                }
                                cache[cacheKey] = parsedExpression;
                            }
                            return addInterceptor(parsedExpression, interceptorFn);
                        case 'function':
                            return addInterceptor(exp, interceptorFn);
                        default:
                            return addInterceptor(noop, interceptorFn);
                    }
                }
    
                function expensiveChecksInterceptor(fn) {
                    if (!fn) return fn;
                    expensiveCheckFn.$$watchDelegate = fn.$$watchDelegate;
                    expensiveCheckFn.assign = expensiveChecksInterceptor(fn.assign);
                    expensiveCheckFn.constant = fn.constant;
                    expensiveCheckFn.literal = fn.literal;
                    for (var i = 0; fn.inputs && i < fn.inputs.length; ++i) {
                        fn.inputs[i] = expensiveChecksInterceptor(fn.inputs[i]);
                    }
                    expensiveCheckFn.inputs = fn.inputs;
                    return expensiveCheckFn;
    
                    function expensiveCheckFn(scope, locals, assign, inputs) {
                        var expensiveCheckOldValue = runningChecksEnabled;
                        runningChecksEnabled = true;
                        try {
                            return fn(scope, locals, assign, inputs);
                        } finally {
                            runningChecksEnabled = expensiveCheckOldValue;
                        }
                    }
                }
    
                function expressionInputDirtyCheck(newValue, oldValueOfValue) {
                    if (newValue == null || oldValueOfValue == null) {
                        return newValue === oldValueOfValue;
                    }
                    if (typeof newValue === 'object') {
                        newValue = getValueOf(newValue);
                        if (typeof newValue === 'object') {
                            return false;
                        }
                    }
                    return newValue === oldValueOfValue || (newValue !== newValue && oldValueOfValue !== oldValueOfValue);
                }
    
                function inputsWatchDelegate(scope, listener, objectEquality, parsedExpression, prettyPrintExpression) {
                    var inputExpressions = parsedExpression.inputs;
                    var lastResult;
                    if (inputExpressions.length === 1) {
                        var oldInputValueOf = expressionInputDirtyCheck;
                        inputExpressions = inputExpressions[0];
                        return scope.$watch(function expressionInputWatch(scope) {
                            var newInputValue = inputExpressions(scope);
                            if (!expressionInputDirtyCheck(newInputValue, oldInputValueOf)) {
                                lastResult = parsedExpression(scope, undefined, undefined, [newInputValue]);
                                oldInputValueOf = newInputValue && getValueOf(newInputValue);
                            }
                            return lastResult;
                        }, listener, objectEquality, prettyPrintExpression);
                    }
                    var oldInputValueOfValues = [];
                    var oldInputValues = [];
                    for (var i = 0, ii = inputExpressions.length; i < ii; i++) {
                        oldInputValueOfValues[i] = expressionInputDirtyCheck;
                        oldInputValues[i] = null;
                    }
                    return scope.$watch(function expressionInputsWatch(scope) {
                        var changed = false;
                        for (var i = 0, ii = inputExpressions.length; i < ii; i++) {
                            var newInputValue = inputExpressions[i](scope);
                            if (changed || (changed = !expressionInputDirtyCheck(newInputValue, oldInputValueOfValues[i]))) {
                                oldInputValues[i] = newInputValue;
                                oldInputValueOfValues[i] = newInputValue && getValueOf(newInputValue);
                            }
                        }
                        if (changed) {
                            lastResult = parsedExpression(scope, undefined, undefined, oldInputValues);
                        }
                        return lastResult;
                    }, listener, objectEquality, prettyPrintExpression);
                }
    
                function oneTimeWatchDelegate(scope, listener, objectEquality, parsedExpression) {
                    var unwatch, lastValue;
                    return unwatch = scope.$watch(function oneTimeWatch(scope) {
                        return parsedExpression(scope);
                    }, function oneTimeListener(value, old, scope) {
                        lastValue = value;
                        if (isFunction(listener)) {
                            listener.apply(this, arguments);
                        }
                        if (isDefined(value)) {
                            scope.$$postDigest(function() {
                                if (isDefined(lastValue)) {
                                    unwatch();
                                }
                            });
                        }
                    }, objectEquality);
                }
    
                function oneTimeLiteralWatchDelegate(scope, listener, objectEquality, parsedExpression) {
                    var unwatch, lastValue;
                    return unwatch = scope.$watch(function oneTimeWatch(scope) {
                        return parsedExpression(scope);
                    }, function oneTimeListener(value, old, scope) {
                        lastValue = value;
                        if (isFunction(listener)) {
                            listener.call(this, value, old, scope);
                        }
                        if (isAllDefined(value)) {
                            scope.$$postDigest(function() {
                                if (isAllDefined(lastValue)) unwatch();
                            });
                        }
                    }, objectEquality);
    
                    function isAllDefined(value) {
                        var allDefined = true;
                        forEach(value, function(val) {
                            if (!isDefined(val)) allDefined = false;
                        });
                        return allDefined;
                    }
                }
    
                function constantWatchDelegate(scope, listener, objectEquality, parsedExpression) {
                    var unwatch;
                    return unwatch = scope.$watch(function constantWatch(scope) {
                        unwatch();
                        return parsedExpression(scope);
                    }, listener, objectEquality);
                }
    
                function addInterceptor(parsedExpression, interceptorFn) {
                    if (!interceptorFn) return parsedExpression;
                    var watchDelegate = parsedExpression.$$watchDelegate;
                    var useInputs = false;
                    var regularWatch =
                        watchDelegate !== oneTimeLiteralWatchDelegate &&
                        watchDelegate !== oneTimeWatchDelegate;
                    var fn = regularWatch ? function regularInterceptedExpression(scope, locals, assign, inputs) {
                        var value = useInputs && inputs ? inputs[0] : parsedExpression(scope, locals, assign, inputs);
                        return interceptorFn(value, scope, locals);
                    } : function oneTimeInterceptedExpression(scope, locals, assign, inputs) {
                        var value = parsedExpression(scope, locals, assign, inputs);
                        var result = interceptorFn(value, scope, locals);
                        return isDefined(value) ? result : value;
                    };
                    if (parsedExpression.$$watchDelegate &&
                        parsedExpression.$$watchDelegate !== inputsWatchDelegate) {
                        fn.$$watchDelegate = parsedExpression.$$watchDelegate;
                    } else if (!interceptorFn.$stateful) {
                        fn.$$watchDelegate = inputsWatchDelegate;
                        useInputs = !parsedExpression.inputs;
                        fn.inputs = parsedExpression.inputs ? parsedExpression.inputs : [parsedExpression];
                    }
                    return fn;
                }
            }];
        }
    
        function $QProvider() {
            this.$get = ['$rootScope', '$exceptionHandler', function($rootScope, $exceptionHandler) {
                return qFactory(function(callback) {
                    $rootScope.$evalAsync(callback);
                }, $exceptionHandler);
            }];
        }
    
        function $$QProvider() {
            this.$get = ['$browser', '$exceptionHandler', function($browser, $exceptionHandler) {
                return qFactory(function(callback) {
                    $browser.defer(callback);
                }, $exceptionHandler);
            }];
        }
    
        function qFactory(nextTick, exceptionHandler) {
            var $qMinErr = minErr('$q', TypeError);
            var defer = function() {
                var d = new Deferred();
                d.resolve = simpleBind(d, d.resolve);
                d.reject = simpleBind(d, d.reject);
                d.notify = simpleBind(d, d.notify);
                return d;
            };
    
            function Promise() {
                this.$$state = {
                    status: 0
                };
            }
            extend(Promise.prototype, {
                then: function(onFulfilled, onRejected, progressBack) {
                    if (isUndefined(onFulfilled) && isUndefined(onRejected) && isUndefined(progressBack)) {
                        return this;
                    }
                    var result = new Deferred();
                    this.$$state.pending = this.$$state.pending || [];
                    this.$$state.pending.push([result, onFulfilled, onRejected, progressBack]);
                    if (this.$$state.status > 0) scheduleProcessQueue(this.$$state);
                    return result.promise;
                },
                "catch": function(callback) {
                    return this.then(null, callback);
                },
                "finally": function(callback, progressBack) {
                    return this.then(function(value) {
                        return handleCallback(value, true, callback);
                    }, function(error) {
                        return handleCallback(error, false, callback);
                    }, progressBack);
                }
            });
    
            function simpleBind(context, fn) {
                return function(value) {
                    fn.call(context, value);
                };
            }
    
            function processQueue(state) {
                var fn, deferred, pending;
                pending = state.pending;
                state.processScheduled = false;
                state.pending = undefined;
                for (var i = 0, ii = pending.length; i < ii; ++i) {
                    deferred = pending[i][0];
                    fn = pending[i][state.status];
                    try {
                        if (isFunction(fn)) {
                            deferred.resolve(fn(state.value));
                        } else if (state.status === 1) {
                            deferred.resolve(state.value);
                        } else {
                            deferred.reject(state.value);
                        }
                    } catch (e) {
                        deferred.reject(e);
                        exceptionHandler(e);
                    }
                }
            }
    
            function scheduleProcessQueue(state) {
                if (state.processScheduled || !state.pending) return;
                state.processScheduled = true;
                nextTick(function() {
                    processQueue(state);
                });
            }
    
            function Deferred() {
                this.promise = new Promise();
            }
            extend(Deferred.prototype, {
                resolve: function(val) {
                    if (this.promise.$$state.status) return;
                    if (val === this.promise) {
                        this.$$reject($qMinErr(
                            'qcycle',
                            "Expected promise to be resolved with value other than itself '{0}'",
                            val));
                    } else {
                        this.$$resolve(val);
                    }
                },
                $$resolve: function(val) {
                    var then;
                    var that = this;
                    var done = false;
                    try {
                        if ((isObject(val) || isFunction(val))) then = val && val.then;
                        if (isFunction(then)) {
                            this.promise.$$state.status = -1;
                            then.call(val, resolvePromise, rejectPromise, simpleBind(this, this.notify));
                        } else {
                            this.promise.$$state.value = val;
                            this.promise.$$state.status = 1;
                            scheduleProcessQueue(this.promise.$$state);
                        }
                    } catch (e) {
                        rejectPromise(e);
                        exceptionHandler(e);
                    }
    
                    function resolvePromise(val) {
                        if (done) return;
                        done = true;
                        that.$$resolve(val);
                    }
    
                    function rejectPromise(val) {
                        if (done) return;
                        done = true;
                        that.$$reject(val);
                    }
                },
                reject: function(reason) {
                    if (this.promise.$$state.status) return;
                    this.$$reject(reason);
                },
                $$reject: function(reason) {
                    this.promise.$$state.value = reason;
                    this.promise.$$state.status = 2;
                    scheduleProcessQueue(this.promise.$$state);
                },
                notify: function(progress) {
                    var callbacks = this.promise.$$state.pending;
                    if ((this.promise.$$state.status <= 0) && callbacks && callbacks.length) {
                        nextTick(function() {
                            var callback, result;
                            for (var i = 0, ii = callbacks.length; i < ii; i++) {
                                result = callbacks[i][0];
                                callback = callbacks[i][3];
                                try {
                                    result.notify(isFunction(callback) ? callback(progress) : progress);
                                } catch (e) {
                                    exceptionHandler(e);
                                }
                            }
                        });
                    }
                }
            });
            var reject = function(reason) {
                var result = new Deferred();
                result.reject(reason);
                return result.promise;
            };
            var makePromise = function makePromise(value, resolved) {
                var result = new Deferred();
                if (resolved) {
                    result.resolve(value);
                } else {
                    result.reject(value);
                }
                return result.promise;
            };
            var handleCallback = function handleCallback(value, isResolved, callback) {
                var callbackOutput = null;
                try {
                    if (isFunction(callback)) callbackOutput = callback();
                } catch (e) {
                    return makePromise(e, false);
                }
                if (isPromiseLike(callbackOutput)) {
                    return callbackOutput.then(function() {
                        return makePromise(value, isResolved);
                    }, function(error) {
                        return makePromise(error, false);
                    });
                } else {
                    return makePromise(value, isResolved);
                }
            };
            var when = function(value, callback, errback, progressBack) {
                var result = new Deferred();
                result.resolve(value);
                return result.promise.then(callback, errback, progressBack);
            };
            var resolve = when;
    
            function all(promises) {
                var deferred = new Deferred(),
                    counter = 0,
                    results = isArray(promises) ? [] : {};
                forEach(promises, function(promise, key) {
                    counter++;
                    when(promise).then(function(value) {
                        if (results.hasOwnProperty(key)) return;
                        results[key] = value;
                        if (!(--counter)) deferred.resolve(results);
                    }, function(reason) {
                        if (results.hasOwnProperty(key)) return;
                        deferred.reject(reason);
                    });
                });
                if (counter === 0) {
                    deferred.resolve(results);
                }
                return deferred.promise;
            }
            var $Q = function Q(resolver) {
                if (!isFunction(resolver)) {
                    throw $qMinErr('norslvr', "Expected resolverFn, got '{0}'", resolver);
                }
                var deferred = new Deferred();
    
                function resolveFn(value) {
                    deferred.resolve(value);
                }
    
                function rejectFn(reason) {
                    deferred.reject(reason);
                }
                resolver(resolveFn, rejectFn);
                return deferred.promise;
            };
            $Q.prototype = Promise.prototype;
            $Q.defer = defer;
            $Q.reject = reject;
            $Q.when = when;
            $Q.resolve = resolve;
            $Q.all = all;
            return $Q;
        }
    
        function $$RAFProvider() {
            this.$get = ['$window', '$timeout', function($window, $timeout) {
                var requestAnimationFrame = $window.requestAnimationFrame ||
                    $window.webkitRequestAnimationFrame;
                var cancelAnimationFrame = $window.cancelAnimationFrame ||
                    $window.webkitCancelAnimationFrame ||
                    $window.webkitCancelRequestAnimationFrame;
                var rafSupported = !!requestAnimationFrame;
                var raf = rafSupported ?
                    function(fn) {
                        var id = requestAnimationFrame(fn);
                        return function() {
                            cancelAnimationFrame(id);
                        };
                    } :
                    function(fn) {
                        var timer = $timeout(fn, 16.66, false);
                        return function() {
                            $timeout.cancel(timer);
                        };
                    };
                raf.supported = rafSupported;
                return raf;
            }];
        }
    
        function $RootScopeProvider() {
            var TTL = 10;
            var $rootScopeMinErr = minErr('$rootScope');
            var lastDirtyWatch = null;
            var applyAsyncId = null;
            this.digestTtl = function(value) {
                if (arguments.length) {
                    TTL = value;
                }
                return TTL;
            };
    
            function createChildScopeClass(parent) {
                function ChildScope() {
                    this.$$watchers = this.$$nextSibling =
                        this.$$childHead = this.$$childTail = null;
                    this.$$listeners = {};
                    this.$$listenerCount = {};
                    this.$$watchersCount = 0;
                    this.$id = nextUid();
                    this.$$ChildScope = null;
                }
                ChildScope.prototype = parent;
                return ChildScope;
            }
            this.$get = ['$exceptionHandler', '$parse', '$browser',
                function($exceptionHandler, $parse, $browser) {
                    function destroyChildScope($event) {
                        $event.currentScope.$$destroyed = true;
                    }
    
                    function cleanUpScope($scope) {
                        if (msie === 9) {
                            $scope.$$childHead && cleanUpScope($scope.$$childHead);
                            $scope.$$nextSibling && cleanUpScope($scope.$$nextSibling);
                        }
                        $scope.$parent = $scope.$$nextSibling = $scope.$$prevSibling = $scope.$$childHead =
                            $scope.$$childTail = $scope.$root = $scope.$$watchers = null;
                    }
    
                    function Scope() {
                        this.$id = nextUid();
                        this.$$phase = this.$parent = this.$$watchers =
                            this.$$nextSibling = this.$$prevSibling =
                            this.$$childHead = this.$$childTail = null;
                        this.$root = this;
                        this.$$destroyed = false;
                        this.$$listeners = {};
                        this.$$listenerCount = {};
                        this.$$watchersCount = 0;
                        this.$$isolateBindings = null;
                    }
                    Scope.prototype = {
                        constructor: Scope,
                        $new: function(isolate, parent) {
                            var child;
                            parent = parent || this;
                            if (isolate) {
                                child = new Scope();
                                child.$root = this.$root;
                            } else {
                                if (!this.$$ChildScope) {
                                    this.$$ChildScope = createChildScopeClass(this);
                                }
                                child = new this.$$ChildScope();
                            }
                            child.$parent = parent;
                            child.$$prevSibling = parent.$$childTail;
                            if (parent.$$childHead) {
                                parent.$$childTail.$$nextSibling = child;
                                parent.$$childTail = child;
                            } else {
                                parent.$$childHead = parent.$$childTail = child;
                            }
                            if (isolate || parent != this) child.$on('$destroy', destroyChildScope);
                            return child;
                        },
                        $watch: function(watchExp, listener, objectEquality, prettyPrintExpression) {
                            var get = $parse(watchExp);
                            if (get.$$watchDelegate) {
                                return get.$$watchDelegate(this, listener, objectEquality, get, watchExp);
                            }
                            var scope = this,
                                array = scope.$$watchers,
                                watcher = {
                                    fn: listener,
                                    last: initWatchVal,
                                    get: get,
                                    exp: prettyPrintExpression || watchExp,
                                    eq: !!objectEquality
                                };
                            lastDirtyWatch = null;
                            if (!isFunction(listener)) {
                                watcher.fn = noop;
                            }
                            if (!array) {
                                array = scope.$$watchers = [];
                            }
                            array.unshift(watcher);
                            incrementWatchersCount(this, 1);
                            return function deregisterWatch() {
                                if (arrayRemove(array, watcher) >= 0) {
                                    incrementWatchersCount(scope, -1);
                                }
                                lastDirtyWatch = null;
                            };
                        },
                        $watchGroup: function(watchExpressions, listener) {
                            var oldValues = new Array(watchExpressions.length);
                            var newValues = new Array(watchExpressions.length);
                            var deregisterFns = [];
                            var self = this;
                            var changeReactionScheduled = false;
                            var firstRun = true;
                            if (!watchExpressions.length) {
                                var shouldCall = true;
                                self.$evalAsync(function() {
                                    if (shouldCall) listener(newValues, newValues, self);
                                });
                                return function deregisterWatchGroup() {
                                    shouldCall = false;
                                };
                            }
                            if (watchExpressions.length === 1) {
                                return this.$watch(watchExpressions[0], function watchGroupAction(value, oldValue, scope) {
                                    newValues[0] = value;
                                    oldValues[0] = oldValue;
                                    listener(newValues, (value === oldValue) ? newValues : oldValues, scope);
                                });
                            }
                            forEach(watchExpressions, function(expr, i) {
                                var unwatchFn = self.$watch(expr, function watchGroupSubAction(value, oldValue) {
                                    newValues[i] = value;
                                    oldValues[i] = oldValue;
                                    if (!changeReactionScheduled) {
                                        changeReactionScheduled = true;
                                        self.$evalAsync(watchGroupAction);
                                    }
                                });
                                deregisterFns.push(unwatchFn);
                            });
    
                            function watchGroupAction() {
                                changeReactionScheduled = false;
                                if (firstRun) {
                                    firstRun = false;
                                    listener(newValues, newValues, self);
                                } else {
                                    listener(newValues, oldValues, self);
                                }
                            }
                            return function deregisterWatchGroup() {
                                while (deregisterFns.length) {
                                    deregisterFns.shift()();
                                }
                            };
                        },
                        $watchCollection: function(obj, listener) {
                            $watchCollectionInterceptor.$stateful = true;
                            var self = this;
                            var newValue;
                            var oldValue;
                            var veryOldValue;
                            var trackVeryOldValue = (listener.length > 1);
                            var changeDetected = 0;
                            var changeDetector = $parse(obj, $watchCollectionInterceptor);
                            var internalArray = [];
                            var internalObject = {};
                            var initRun = true;
                            var oldLength = 0;
    
                            function $watchCollectionInterceptor(_value) {
                                newValue = _value;
                                var newLength, key, bothNaN, newItem, oldItem;
                                if (isUndefined(newValue)) return;
                                if (!isObject(newValue)) {
                                    if (oldValue !== newValue) {
                                        oldValue = newValue;
                                        changeDetected++;
                                    }
                                } else if (isArrayLike(newValue)) {
                                    if (oldValue !== internalArray) {
                                        oldValue = internalArray;
                                        oldLength = oldValue.length = 0;
                                        changeDetected++;
                                    }
                                    newLength = newValue.length;
                                    if (oldLength !== newLength) {
                                        changeDetected++;
                                        oldValue.length = oldLength = newLength;
                                    }
                                    for (var i = 0; i < newLength; i++) {
                                        oldItem = oldValue[i];
                                        newItem = newValue[i];
                                        bothNaN = (oldItem !== oldItem) && (newItem !== newItem);
                                        if (!bothNaN && (oldItem !== newItem)) {
                                            changeDetected++;
                                            oldValue[i] = newItem;
                                        }
                                    }
                                } else {
                                    if (oldValue !== internalObject) {
                                        oldValue = internalObject = {};
                                        oldLength = 0;
                                        changeDetected++;
                                    }
                                    newLength = 0;
                                    for (key in newValue) {
                                        if (hasOwnProperty.call(newValue, key)) {
                                            newLength++;
                                            newItem = newValue[key];
                                            oldItem = oldValue[key];
                                            if (key in oldValue) {
                                                bothNaN = (oldItem !== oldItem) && (newItem !== newItem);
                                                if (!bothNaN && (oldItem !== newItem)) {
                                                    changeDetected++;
                                                    oldValue[key] = newItem;
                                                }
                                            } else {
                                                oldLength++;
                                                oldValue[key] = newItem;
                                                changeDetected++;
                                            }
                                        }
                                    }
                                    if (oldLength > newLength) {
                                        changeDetected++;
                                        for (key in oldValue) {
                                            if (!hasOwnProperty.call(newValue, key)) {
                                                oldLength--;
                                                delete oldValue[key];
                                            }
                                        }
                                    }
                                }
                                return changeDetected;
                            }
    
                            function $watchCollectionAction() {
                                if (initRun) {
                                    initRun = false;
                                    listener(newValue, newValue, self);
                                } else {
                                    listener(newValue, veryOldValue, self);
                                }
                                if (trackVeryOldValue) {
                                    if (!isObject(newValue)) {
                                        veryOldValue = newValue;
                                    } else if (isArrayLike(newValue)) {
                                        veryOldValue = new Array(newValue.length);
                                        for (var i = 0; i < newValue.length; i++) {
                                            veryOldValue[i] = newValue[i];
                                        }
                                    } else {
                                        veryOldValue = {};
                                        for (var key in newValue) {
                                            if (hasOwnProperty.call(newValue, key)) {
                                                veryOldValue[key] = newValue[key];
                                            }
                                        }
                                    }
                                }
                            }
                            return this.$watch(changeDetector, $watchCollectionAction);
                        },
                        $digest: function() {
                            var watch, value, last, fn, get,
                                watchers,
                                length,
                                dirty, ttl = TTL,
                                next, current, target = this,
                                watchLog = [],
                                logIdx, asyncTask;
                            beginPhase('$digest');
                            $browser.$$checkUrlChange();
                            if (this === $rootScope && applyAsyncId !== null) {
                                $browser.defer.cancel(applyAsyncId);
                                flushApplyAsync();
                            }
                            lastDirtyWatch = null;
                            do {
                                dirty = false;
                                current = target;
                                while (asyncQueue.length) {
                                    try {
                                        asyncTask = asyncQueue.shift();
                                        asyncTask.scope.$eval(asyncTask.expression, asyncTask.locals);
                                    } catch (e) {
                                        $exceptionHandler(e);
                                    }
                                    lastDirtyWatch = null;
                                }
                                traverseScopesLoop:
                                    do {
                                        if ((watchers = current.$$watchers)) {
                                            length = watchers.length;
                                            while (length--) {
                                                try {
                                                    watch = watchers[length];
                                                    if (watch) {
                                                        get = watch.get;
                                                        if ((value = get(current)) !== (last = watch.last) &&
                                                            !(watch.eq ?
                                                                equals(value, last) :
                                                                (typeof value === 'number' && typeof last === 'number' &&
                                                                    isNaN(value) && isNaN(last)))) {
                                                            dirty = true;
                                                            lastDirtyWatch = watch;
                                                            watch.last = watch.eq ? copy(value, null) : value;
                                                            fn = watch.fn;
                                                            fn(value, ((last === initWatchVal) ? value : last), current);
                                                            if (ttl < 5) {
                                                                logIdx = 4 - ttl;
                                                                if (!watchLog[logIdx]) watchLog[logIdx] = [];
                                                                watchLog[logIdx].push({
                                                                    msg: isFunction(watch.exp) ? 'fn: ' + (watch.exp.name || watch.exp.toString()) : watch.exp,
                                                                    newVal: value,
                                                                    oldVal: last
                                                                });
                                                            }
                                                        } else if (watch === lastDirtyWatch) {
                                                            dirty = false;
                                                            break traverseScopesLoop;
                                                        }
                                                    }
                                                } catch (e) {
                                                    $exceptionHandler(e);
                                                }
                                            }
                                        }
                                        if (!(next = ((current.$$watchersCount && current.$$childHead) ||
                                                (current !== target && current.$$nextSibling)))) {
                                            while (current !== target && !(next = current.$$nextSibling)) {
                                                current = current.$parent;
                                            }
                                        }
                                    } while ((current = next));
                                if ((dirty || asyncQueue.length) && !(ttl--)) {
                                    clearPhase();
                                    throw $rootScopeMinErr('infdig',
                                        '{0} $digest() iterations reached. Aborting!\n' +
                                        'Watchers fired in the last 5 iterations: {1}',
                                        TTL, watchLog);
                                }
                            } while (dirty || asyncQueue.length);
                            clearPhase();
                            while (postDigestQueue.length) {
                                try {
                                    postDigestQueue.shift()();
                                } catch (e) {
                                    $exceptionHandler(e);
                                }
                            }
                        },
                        $destroy: function() {
                            if (this.$$destroyed) return;
                            var parent = this.$parent;
                            this.$broadcast('$destroy');
                            this.$$destroyed = true;
                            if (this === $rootScope) {
                                $browser.$$applicationDestroyed();
                            }
                            incrementWatchersCount(this, -this.$$watchersCount);
                            for (var eventName in this.$$listenerCount) {
                                decrementListenerCount(this, this.$$listenerCount[eventName], eventName);
                            }
                            if (parent && parent.$$childHead == this) parent.$$childHead = this.$$nextSibling;
                            if (parent && parent.$$childTail == this) parent.$$childTail = this.$$prevSibling;
                            if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;
                            if (this.$$nextSibling) this.$$nextSibling.$$prevSibling = this.$$prevSibling;
                            this.$destroy = this.$digest = this.$apply = this.$evalAsync = this.$applyAsync = noop;
                            this.$on = this.$watch = this.$watchGroup = function() {
                                return noop;
                            };
                            this.$$listeners = {};
                            this.$$nextSibling = null;
                            cleanUpScope(this);
                        },
                        $eval: function(expr, locals) {
                            return $parse(expr)(this, locals);
                        },
                        $evalAsync: function(expr, locals) {
                            if (!$rootScope.$$phase && !asyncQueue.length) {
                                $browser.defer(function() {
                                    if (asyncQueue.length) {
                                        $rootScope.$digest();
                                    }
                                });
                            }
                            asyncQueue.push({
                                scope: this,
                                expression: $parse(expr),
                                locals: locals
                            });
                        },
                        $$postDigest: function(fn) {
                            postDigestQueue.push(fn);
                        },
                        $apply: function(expr) {
                            try {
                                beginPhase('$apply');
                                try {
                                    return this.$eval(expr);
                                } finally {
                                    clearPhase();
                                }
                            } catch (e) {
                                $exceptionHandler(e);
                            } finally {
                                try {
                                    $rootScope.$digest();
                                } catch (e) {
                                    $exceptionHandler(e);
                                    throw e;
                                }
                            }
                        },
                        $applyAsync: function(expr) {
                            var scope = this;
                            expr && applyAsyncQueue.push($applyAsyncExpression);
                            expr = $parse(expr);
                            scheduleApplyAsync();
    
                            function $applyAsyncExpression() {
                                scope.$eval(expr);
                            }
                        },
                        $on: function(name, listener) {
                            var namedListeners = this.$$listeners[name];
                            if (!namedListeners) {
                                this.$$listeners[name] = namedListeners = [];
                            }
                            namedListeners.push(listener);
                            var current = this;
                            do {
                                if (!current.$$listenerCount[name]) {
                                    current.$$listenerCount[name] = 0;
                                }
                                current.$$listenerCount[name]++;
                            } while ((current = current.$parent));
                            var self = this;
                            return function() {
                                var indexOfListener = namedListeners.indexOf(listener);
                                if (indexOfListener !== -1) {
                                    namedListeners[indexOfListener] = null;
                                    decrementListenerCount(self, 1, name);
                                }
                            };
                        },
                        $emit: function(name, args) {
                            var empty = [],
                                namedListeners,
                                scope = this,
                                stopPropagation = false,
                                event = {
                                    name: name,
                                    targetScope: scope,
                                    stopPropagation: function() {
                                        stopPropagation = true;
                                    },
                                    preventDefault: function() {
                                        event.defaultPrevented = true;
                                    },
                                    defaultPrevented: false
                                },
                                listenerArgs = concat([event], arguments, 1),
                                i, length;
                            do {
                                namedListeners = scope.$$listeners[name] || empty;
                                event.currentScope = scope;
                                for (i = 0, length = namedListeners.length; i < length; i++) {
                                    if (!namedListeners[i]) {
                                        namedListeners.splice(i, 1);
                                        i--;
                                        length--;
                                        continue;
                                    }
                                    try {
                                        namedListeners[i].apply(null, listenerArgs);
                                    } catch (e) {
                                        $exceptionHandler(e);
                                    }
                                }
                                if (stopPropagation) {
                                    event.currentScope = null;
                                    return event;
                                }
                                scope = scope.$parent;
                            } while (scope);
                            event.currentScope = null;
                            return event;
                        },
                        $broadcast: function(name, args) {
                            var target = this,
                                current = target,
                                next = target,
                                event = {
                                    name: name,
                                    targetScope: target,
                                    preventDefault: function() {
                                        event.defaultPrevented = true;
                                    },
                                    defaultPrevented: false
                                };
                            if (!target.$$listenerCount[name]) return event;
                            var listenerArgs = concat([event], arguments, 1),
                                listeners, i, length;
                            while ((current = next)) {
                                event.currentScope = current;
                                listeners = current.$$listeners[name] || [];
                                for (i = 0, length = listeners.length; i < length; i++) {
                                    if (!listeners[i]) {
                                        listeners.splice(i, 1);
                                        i--;
                                        length--;
                                        continue;
                                    }
                                    try {
                                        listeners[i].apply(null, listenerArgs);
                                    } catch (e) {
                                        $exceptionHandler(e);
                                    }
                                }
                                if (!(next = ((current.$$listenerCount[name] && current.$$childHead) ||
                                        (current !== target && current.$$nextSibling)))) {
                                    while (current !== target && !(next = current.$$nextSibling)) {
                                        current = current.$parent;
                                    }
                                }
                            }
                            event.currentScope = null;
                            return event;
                        }
                    };
                    var $rootScope = new Scope();
                    var asyncQueue = $rootScope.$$asyncQueue = [];
                    var postDigestQueue = $rootScope.$$postDigestQueue = [];
                    var applyAsyncQueue = $rootScope.$$applyAsyncQueue = [];
                    return $rootScope;
    
                    function beginPhase(phase) {
                        if ($rootScope.$$phase) {
                            throw $rootScopeMinErr('inprog', '{0} already in progress', $rootScope.$$phase);
                        }
                        $rootScope.$$phase = phase;
                    }
    
                    function clearPhase() {
                        $rootScope.$$phase = null;
                    }
    
                    function incrementWatchersCount(current, count) {
                        do {
                            current.$$watchersCount += count;
                        } while ((current = current.$parent));
                    }
    
                    function decrementListenerCount(current, count, name) {
                        do {
                            current.$$listenerCount[name] -= count;
                            if (current.$$listenerCount[name] === 0) {
                                delete current.$$listenerCount[name];
                            }
                        } while ((current = current.$parent));
                    }
    
                    function initWatchVal() {}
    
                    function flushApplyAsync() {
                        while (applyAsyncQueue.length) {
                            try {
                                applyAsyncQueue.shift()();
                            } catch (e) {
                                $exceptionHandler(e);
                            }
                        }
                        applyAsyncId = null;
                    }
    
                    function scheduleApplyAsync() {
                        if (applyAsyncId === null) {
                            applyAsyncId = $browser.defer(function() {
                                $rootScope.$apply(flushApplyAsync);
                            });
                        }
                    }
                }
            ];
        }
    
        function $$SanitizeUriProvider() {
            var aHrefSanitizationWhitelist = /^\s*(https?|ftp|mailto|tel|file):/,
                imgSrcSanitizationWhitelist = /^\s*((https?|ftp|file|blob):|data:image\/)/;
            this.aHrefSanitizationWhitelist = function(regexp) {
                if (isDefined(regexp)) {
                    aHrefSanitizationWhitelist = regexp;
                    return this;
                }
                return aHrefSanitizationWhitelist;
            };
            this.imgSrcSanitizationWhitelist = function(regexp) {
                if (isDefined(regexp)) {
                    imgSrcSanitizationWhitelist = regexp;
                    return this;
                }
                return imgSrcSanitizationWhitelist;
            };
            this.$get = function() {
                return function sanitizeUri(uri, isImage) {
                    var regex = isImage ? imgSrcSanitizationWhitelist : aHrefSanitizationWhitelist;
                    var normalizedVal;
                    normalizedVal = urlResolve(uri).href;
                    if (normalizedVal !== '' && !normalizedVal.match(regex)) {
                        return 'unsafe:' + normalizedVal;
                    }
                    return uri;
                };
            };
        }
        var $sceMinErr = minErr('$sce');
        var SCE_CONTEXTS = {
            HTML: 'html',
            CSS: 'css',
            URL: 'url',
            RESOURCE_URL: 'resourceUrl',
            JS: 'js'
        };
    
        function adjustMatcher(matcher) {
            if (matcher === 'self') {
                return matcher;
            } else if (isString(matcher)) {
                if (matcher.indexOf('***') > -1) {
                    throw $sceMinErr('iwcard',
                        'Illegal sequence *** in string matcher.  String: {0}', matcher);
                }
                matcher = escapeForRegexp(matcher).
                replace('\\*\\*', '.*').
                replace('\\*', '[^:/.?&;]*');
                return new RegExp('^' + matcher + '$');
            } else if (isRegExp(matcher)) {
                return new RegExp('^' + matcher.source + '$');
            } else {
                throw $sceMinErr('imatcher',
                    'Matchers may only be "self", string patterns or RegExp objects');
            }
        }
    
        function adjustMatchers(matchers) {
            var adjustedMatchers = [];
            if (isDefined(matchers)) {
                forEach(matchers, function(matcher) {
                    adjustedMatchers.push(adjustMatcher(matcher));
                });
            }
            return adjustedMatchers;
        }
    
        function $SceDelegateProvider() {
            this.SCE_CONTEXTS = SCE_CONTEXTS;
            var resourceUrlWhitelist = ['self'],
                resourceUrlBlacklist = [];
            this.resourceUrlWhitelist = function(value) {
                if (arguments.length) {
                    resourceUrlWhitelist = adjustMatchers(value);
                }
                return resourceUrlWhitelist;
            };
            this.resourceUrlBlacklist = function(value) {
                if (arguments.length) {
                    resourceUrlBlacklist = adjustMatchers(value);
                }
                return resourceUrlBlacklist;
            };
            this.$get = ['$injector', function($injector) {
                var htmlSanitizer = function htmlSanitizer(html) {
                    throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');
                };
                if ($injector.has('$sanitize')) {
                    htmlSanitizer = $injector.get('$sanitize');
                }
    
                function matchUrl(matcher, parsedUrl) {
                    if (matcher === 'self') {
                        return urlIsSameOrigin(parsedUrl);
                    } else {
                        return !!matcher.exec(parsedUrl.href);
                    }
                }
    
                function isResourceUrlAllowedByPolicy(url) {
                    var parsedUrl = urlResolve(url.toString());
                    var i, n, allowed = false;
                    for (i = 0, n = resourceUrlWhitelist.length; i < n; i++) {
                        if (matchUrl(resourceUrlWhitelist[i], parsedUrl)) {
                            allowed = true;
                            break;
                        }
                    }
                    if (allowed) {
                        for (i = 0, n = resourceUrlBlacklist.length; i < n; i++) {
                            if (matchUrl(resourceUrlBlacklist[i], parsedUrl)) {
                                allowed = false;
                                break;
                            }
                        }
                    }
                    return allowed;
                }
    
                function generateHolderType(Base) {
                    var holderType = function TrustedValueHolderType(trustedValue) {
                        this.$$unwrapTrustedValue = function() {
                            return trustedValue;
                        };
                    };
                    if (Base) {
                        holderType.prototype = new Base();
                    }
                    holderType.prototype.valueOf = function sceValueOf() {
                        return this.$$unwrapTrustedValue();
                    };
                    holderType.prototype.toString = function sceToString() {
                        return this.$$unwrapTrustedValue().toString();
                    };
                    return holderType;
                }
                var trustedValueHolderBase = generateHolderType(),
                    byType = {};
                byType[SCE_CONTEXTS.HTML] = generateHolderType(trustedValueHolderBase);
                byType[SCE_CONTEXTS.CSS] = generateHolderType(trustedValueHolderBase);
                byType[SCE_CONTEXTS.URL] = generateHolderType(trustedValueHolderBase);
                byType[SCE_CONTEXTS.JS] = generateHolderType(trustedValueHolderBase);
                byType[SCE_CONTEXTS.RESOURCE_URL] = generateHolderType(byType[SCE_CONTEXTS.URL]);
    
                function trustAs(type, trustedValue) {
                    var Constructor = (byType.hasOwnProperty(type) ? byType[type] : null);
                    if (!Constructor) {
                        throw $sceMinErr('icontext',
                            'Attempted to trust a value in invalid context. Context: {0}; Value: {1}',
                            type, trustedValue);
                    }
                    if (trustedValue === null || isUndefined(trustedValue) || trustedValue === '') {
                        return trustedValue;
                    }
                    if (typeof trustedValue !== 'string') {
                        throw $sceMinErr('itype',
                            'Attempted to trust a non-string value in a content requiring a string: Context: {0}',
                            type);
                    }
                    return new Constructor(trustedValue);
                }
    
                function valueOf(maybeTrusted) {
                    if (maybeTrusted instanceof trustedValueHolderBase) {
                        return maybeTrusted.$$unwrapTrustedValue();
                    } else {
                        return maybeTrusted;
                    }
                }
    
                function getTrusted(type, maybeTrusted) {
                    if (maybeTrusted === null || isUndefined(maybeTrusted) || maybeTrusted === '') {
                        return maybeTrusted;
                    }
                    var constructor = (byType.hasOwnProperty(type) ? byType[type] : null);
                    if (constructor && maybeTrusted instanceof constructor) {
                        return maybeTrusted.$$unwrapTrustedValue();
                    }
                    if (type === SCE_CONTEXTS.RESOURCE_URL) {
                        if (isResourceUrlAllowedByPolicy(maybeTrusted)) {
                            return maybeTrusted;
                        } else {
                            throw $sceMinErr('insecurl',
                                'Blocked loading resource from url not allowed by $sceDelegate policy.  URL: {0}',
                                maybeTrusted.toString());
                        }
                    } else if (type === SCE_CONTEXTS.HTML) {
                        return htmlSanitizer(maybeTrusted);
                    }
                    throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');
                }
                return {
                    trustAs: trustAs,
                    getTrusted: getTrusted,
                    valueOf: valueOf
                };
            }];
        }
    
        function $SceProvider() {
            var enabled = true;
            this.enabled = function(value) {
                if (arguments.length) {
                    enabled = !!value;
                }
                return enabled;
            };
            this.$get = ['$parse', '$sceDelegate', function(
                $parse, $sceDelegate) {
                if (enabled && msie < 8) {
                    throw $sceMinErr('iequirks',
                        'Strict Contextual Escaping does not support Internet Explorer version < 11 in quirks ' +
                        'mode.  You can fix this by adding the text <!doctype html> to the top of your HTML ' +
                        'document.  See http://docs.angularjs.org/api/ng.$sce for more information.');
                }
                var sce = shallowCopy(SCE_CONTEXTS);
                sce.isEnabled = function() {
                    return enabled;
                };
                sce.trustAs = $sceDelegate.trustAs;
                sce.getTrusted = $sceDelegate.getTrusted;
                sce.valueOf = $sceDelegate.valueOf;
                if (!enabled) {
                    sce.trustAs = sce.getTrusted = function(type, value) {
                        return value;
                    };
                    sce.valueOf = identity;
                }
                sce.parseAs = function sceParseAs(type, expr) {
                    var parsed = $parse(expr);
                    if (parsed.literal && parsed.constant) {
                        return parsed;
                    } else {
                        return $parse(expr, function(value) {
                            return sce.getTrusted(type, value);
                        });
                    }
                };
                var parse = sce.parseAs,
                    getTrusted = sce.getTrusted,
                    trustAs = sce.trustAs;
                forEach(SCE_CONTEXTS, function(enumValue, name) {
                    var lName = lowercase(name);
                    sce[camelCase("parse_as_" + lName)] = function(expr) {
                        return parse(enumValue, expr);
                    };
                    sce[camelCase("get_trusted_" + lName)] = function(value) {
                        return getTrusted(enumValue, value);
                    };
                    sce[camelCase("trust_as_" + lName)] = function(value) {
                        return trustAs(enumValue, value);
                    };
                });
                return sce;
            }];
        }
    
        function $SnifferProvider() {
            this.$get = ['$window', '$document', function($window, $document) {
                var eventSupport = {},
                    isChromePackagedApp = $window.chrome && $window.chrome.app && $window.chrome.app.runtime,
                    hasHistoryPushState = !isChromePackagedApp && $window.history && $window.history.pushState,
                    android =
                    toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),
                    boxee = /Boxee/i.test(($window.navigator || {}).userAgent),
                    document = $document[0] || {},
                    vendorPrefix,
                    vendorRegex = /^(Moz|webkit|ms)(?=[A-Z])/,
                    bodyStyle = document.body && document.body.style,
                    transitions = false,
                    animations = false,
                    match;
                if (bodyStyle) {
                    for (var prop in bodyStyle) {
                        if (match = vendorRegex.exec(prop)) {
                            vendorPrefix = match[0];
                            vendorPrefix = vendorPrefix.substr(0, 1).toUpperCase() + vendorPrefix.substr(1);
                            break;
                        }
                    }
                    if (!vendorPrefix) {
                        vendorPrefix = ('WebkitOpacity' in bodyStyle) && 'webkit';
                    }
                    transitions = !!(('transition' in bodyStyle) || (vendorPrefix + 'Transition' in bodyStyle));
                    animations = !!(('animation' in bodyStyle) || (vendorPrefix + 'Animation' in bodyStyle));
                    if (android && (!transitions || !animations)) {
                        transitions = isString(bodyStyle.webkitTransition);
                        animations = isString(bodyStyle.webkitAnimation);
                    }
                }
                return {
                    history: !!(hasHistoryPushState && !(android < 4) && !boxee),
                    hasEvent: function(event) {
                        if (event === 'input' && msie <= 11) return false;
                        if (isUndefined(eventSupport[event])) {
                            var divElm = document.createElement('div');
                            eventSupport[event] = 'on' + event in divElm;
                        }
                        return eventSupport[event];
                    },
                    csp: csp(),
                    vendorPrefix: vendorPrefix,
                    transitions: transitions,
                    animations: animations,
                    android: android
                };
            }];
        }
        var $templateRequestMinErr = minErr('$compile');
    
        function $TemplateRequestProvider() {
            var httpOptions;
            this.httpOptions = function(val) {
                if (val) {
                    httpOptions = val;
                    return this;
                }
                return httpOptions;
            };
            this.$get = ['$templateCache', '$http', '$q', '$sce', function($templateCache, $http, $q, $sce) {
                function handleRequestFn(tpl, ignoreRequestError) {
                    handleRequestFn.totalPendingRequests++;
                    if (!isString(tpl) || !$templateCache.get(tpl)) {
                        tpl = $sce.getTrustedResourceUrl(tpl);
                    }
                    var transformResponse = $http.defaults && $http.defaults.transformResponse;
                    if (isArray(transformResponse)) {
                        transformResponse = transformResponse.filter(function(transformer) {
                            return transformer !== defaultHttpResponseTransform;
                        });
                    } else if (transformResponse === defaultHttpResponseTransform) {
                        transformResponse = null;
                    }
                    return $http.get(tpl, extend({
                            cache: $templateCache,
                            transformResponse: transformResponse
                        }, httpOptions))['finally'](function() {
                            handleRequestFn.totalPendingRequests--;
                        })
                        .then(function(response) {
                            $templateCache.put(tpl, response.data);
                            return response.data;
                        }, handleError);
    
                    function handleError(resp) {
                        if (!ignoreRequestError) {
                            throw $templateRequestMinErr('tpload', 'Failed to load template: {0} (HTTP status: {1} {2})',
                                tpl, resp.status, resp.statusText);
                        }
                        return $q.reject(resp);
                    }
                }
                handleRequestFn.totalPendingRequests = 0;
                return handleRequestFn;
            }];
        }
    
        function $$TestabilityProvider() {
            this.$get = ['$rootScope', '$browser', '$location',
                function($rootScope, $browser, $location) {
                    var testability = {};
                    testability.findBindings = function(element, expression, opt_exactMatch) {
                        var bindings = element.getElementsByClassName('ng-binding');
                        var matches = [];
                        forEach(bindings, function(binding) {
                            var dataBinding = angular.element(binding).data('$binding');
                            if (dataBinding) {
                                forEach(dataBinding, function(bindingName) {
                                    if (opt_exactMatch) {
                                        var matcher = new RegExp('(^|\\s)' + escapeForRegexp(expression) + '(\\s|\\||$)');
                                        if (matcher.test(bindingName)) {
                                            matches.push(binding);
                                        }
                                    } else {
                                        if (bindingName.indexOf(expression) != -1) {
                                            matches.push(binding);
                                        }
                                    }
                                });
                            }
                        });
                        return matches;
                    };
                    testability.findModels = function(element, expression, opt_exactMatch) {
                        var prefixes = ['ng-', 'data-ng-', 'ng\\:'];
                        for (var p = 0; p < prefixes.length; ++p) {
                            var attributeEquals = opt_exactMatch ? '=' : '*=';
                            var selector = '[' + prefixes[p] + 'model' + attributeEquals + '"' + expression + '"]';
                            var elements = element.querySelectorAll(selector);
                            if (elements.length) {
                                return elements;
                            }
                        }
                    };
                    testability.getLocation = function() {
                        return $location.url();
                    };
                    testability.setLocation = function(url) {
                        if (url !== $location.url()) {
                            $location.url(url);
                            $rootScope.$digest();
                        }
                    };
                    testability.whenStable = function(callback) {
                        $browser.notifyWhenNoOutstandingRequests(callback);
                    };
                    return testability;
                }
            ];
        }
    
        function $TimeoutProvider() {
            this.$get = ['$rootScope', '$browser', '$q', '$$q', '$exceptionHandler',
                function($rootScope, $browser, $q, $$q, $exceptionHandler) {
                    var deferreds = {};
    
                    function timeout(fn, delay, invokeApply) {
                        if (!isFunction(fn)) {
                            invokeApply = delay;
                            delay = fn;
                            fn = noop;
                        }
                        var args = sliceArgs(arguments, 3),
                            skipApply = (isDefined(invokeApply) && !invokeApply),
                            deferred = (skipApply ? $$q : $q).defer(),
                            promise = deferred.promise,
                            timeoutId;
                        timeoutId = $browser.defer(function() {
                            try {
                                deferred.resolve(fn.apply(null, args));
                            } catch (e) {
                                deferred.reject(e);
                                $exceptionHandler(e);
                            } finally {
                                delete deferreds[promise.$$timeoutId];
                            }
                            if (!skipApply) $rootScope.$apply();
                        }, delay);
                        promise.$$timeoutId = timeoutId;
                        deferreds[timeoutId] = deferred;
                        return promise;
                    }
                    timeout.cancel = function(promise) {
                        if (promise && promise.$$timeoutId in deferreds) {
                            deferreds[promise.$$timeoutId].reject('canceled');
                            delete deferreds[promise.$$timeoutId];
                            return $browser.defer.cancel(promise.$$timeoutId);
                        }
                        return false;
                    };
                    return timeout;
                }
            ];
        }
        var urlParsingNode = document.createElement("a");
        var originUrl = urlResolve(window.location.href);
    
        function urlResolve(url) {
            var href = url;
            if (msie) {
                urlParsingNode.setAttribute("href", href);
                href = urlParsingNode.href;
            }
            urlParsingNode.setAttribute('href', href);
            return {
                href: urlParsingNode.href,
                protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
                host: urlParsingNode.host,
                search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
                hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
                hostname: urlParsingNode.hostname,
                port: urlParsingNode.port,
                pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
                    urlParsingNode.pathname :
                    '/' + urlParsingNode.pathname
            };
        }
    
        function urlIsSameOrigin(requestUrl) {
            var parsed = (isString(requestUrl)) ? urlResolve(requestUrl) : requestUrl;
            return (parsed.protocol === originUrl.protocol &&
                parsed.host === originUrl.host);
        }
    
        function $WindowProvider() {
            this.$get = valueFn(window);
        }
    
        function $$CookieReader($document) {
            var rawDocument = $document[0] || {};
            var lastCookies = {};
            var lastCookieString = '';
    
            function safeDecodeURIComponent(str) {
                try {
                    return decodeURIComponent(str);
                } catch (e) {
                    return str;
                }
            }
            return function() {
                var cookieArray, cookie, i, index, name;
                var currentCookieString = rawDocument.cookie || '';
                if (currentCookieString !== lastCookieString) {
                    lastCookieString = currentCookieString;
                    cookieArray = lastCookieString.split('; ');
                    lastCookies = {};
                    for (i = 0; i < cookieArray.length; i++) {
                        cookie = cookieArray[i];
                        index = cookie.indexOf('=');
                        if (index > 0) {
                            name = safeDecodeURIComponent(cookie.substring(0, index));
                            if (isUndefined(lastCookies[name])) {
                                lastCookies[name] = safeDecodeURIComponent(cookie.substring(index + 1));
                            }
                        }
                    }
                }
                return lastCookies;
            };
        }
        $$CookieReader.$inject = ['$document'];
    
        function $$CookieReaderProvider() {
            this.$get = $$CookieReader;
        }
        $FilterProvider.$inject = ['$provide'];
    
        function $FilterProvider($provide) {
            var suffix = 'Filter';
    
            function register(name, factory) {
                if (isObject(name)) {
                    var filters = {};
                    forEach(name, function(filter, key) {
                        filters[key] = register(key, filter);
                    });
                    return filters;
                } else {
                    return $provide.factory(name + suffix, factory);
                }
            }
            this.register = register;
            this.$get = ['$injector', function($injector) {
                return function(name) {
                    return $injector.get(name + suffix);
                };
            }];
            register('currency', currencyFilter);
            register('date', dateFilter);
            register('filter', filterFilter);
            register('json', jsonFilter);
            register('limitTo', limitToFilter);
            register('lowercase', lowercaseFilter);
            register('number', numberFilter);
            register('orderBy', orderByFilter);
            register('uppercase', uppercaseFilter);
        }
    
        function filterFilter() {
            return function(array, expression, comparator) {
                if (!isArrayLike(array)) {
                    if (array == null) {
                        return array;
                    } else {
                        throw minErr('filter')('notarray', 'Expected array but received: {0}', array);
                    }
                }
                var expressionType = getTypeForFilter(expression);
                var predicateFn;
                var matchAgainstAnyProp;
                switch (expressionType) {
                    case 'function':
                        predicateFn = expression;
                        break;
                    case 'boolean':
                    case 'null':
                    case 'number':
                    case 'string':
                        matchAgainstAnyProp = true;
                    case 'object':
                        predicateFn = createPredicateFn(expression, comparator, matchAgainstAnyProp);
                        break;
                    default:
                        return array;
                }
                return Array.prototype.filter.call(array, predicateFn);
            };
        }
    
        function createPredicateFn(expression, comparator, matchAgainstAnyProp) {
            var shouldMatchPrimitives = isObject(expression) && ('$' in expression);
            var predicateFn;
            if (comparator === true) {
                comparator = equals;
            } else if (!isFunction(comparator)) {
                comparator = function(actual, expected) {
                    if (isUndefined(actual)) {
                        return false;
                    }
                    if ((actual === null) || (expected === null)) {
                        return actual === expected;
                    }
                    if (isObject(expected) || (isObject(actual) && !hasCustomToString(actual))) {
                        return false;
                    }
                    actual = lowercase('' + actual);
                    expected = lowercase('' + expected);
                    return actual.indexOf(expected) !== -1;
                };
            }
            predicateFn = function(item) {
                if (shouldMatchPrimitives && !isObject(item)) {
                    return deepCompare(item, expression.$, comparator, false);
                }
                return deepCompare(item, expression, comparator, matchAgainstAnyProp);
            };
            return predicateFn;
        }
    
        function deepCompare(actual, expected, comparator, matchAgainstAnyProp, dontMatchWholeObject) {
            var actualType = getTypeForFilter(actual);
            var expectedType = getTypeForFilter(expected);
            if ((expectedType === 'string') && (expected.charAt(0) === '!')) {
                return !deepCompare(actual, expected.substring(1), comparator, matchAgainstAnyProp);
            } else if (isArray(actual)) {
                return actual.some(function(item) {
                    return deepCompare(item, expected, comparator, matchAgainstAnyProp);
                });
            }
            switch (actualType) {
                case 'object':
                    var key;
                    if (matchAgainstAnyProp) {
                        for (key in actual) {
                            if ((key.charAt(0) !== '$') && deepCompare(actual[key], expected, comparator, true)) {
                                return true;
                            }
                        }
                        return dontMatchWholeObject ? false : deepCompare(actual, expected, comparator, false);
                    } else if (expectedType === 'object') {
                        for (key in expected) {
                            var expectedVal = expected[key];
                            if (isFunction(expectedVal) || isUndefined(expectedVal)) {
                                continue;
                            }
                            var matchAnyProperty = key === '$';
                            var actualVal = matchAnyProperty ? actual : actual[key];
                            if (!deepCompare(actualVal, expectedVal, comparator, matchAnyProperty, matchAnyProperty)) {
                                return false;
                            }
                        }
                        return true;
                    } else {
                        return comparator(actual, expected);
                    }
                    break;
                case 'function':
                    return false;
                default:
                    return comparator(actual, expected);
            }
        }
    
        function getTypeForFilter(val) {
            return (val === null) ? 'null' : typeof val;
        }
        var MAX_DIGITS = 22;
        var DECIMAL_SEP = '.';
        var ZERO_CHAR = '0';
        currencyFilter.$inject = ['$locale'];
    
        function currencyFilter($locale) {
            var formats = $locale.NUMBER_FORMATS;
            return function(amount, currencySymbol, fractionSize) {
                if (isUndefined(currencySymbol)) {
                    currencySymbol = formats.CURRENCY_SYM;
                }
                if (isUndefined(fractionSize)) {
                    fractionSize = formats.PATTERNS[1].maxFrac;
                }
                return (amount == null) ?
                    amount :
                    formatNumber(amount, formats.PATTERNS[1], formats.GROUP_SEP, formats.DECIMAL_SEP, fractionSize).
                replace(/\u00A4/g, currencySymbol);
            };
        }
        numberFilter.$inject = ['$locale'];
    
        function numberFilter($locale) {
            var formats = $locale.NUMBER_FORMATS;
            return function(number, fractionSize) {
                return (number == null) ?
                    number :
                    formatNumber(number, formats.PATTERNS[0], formats.GROUP_SEP, formats.DECIMAL_SEP,
                        fractionSize);
            };
        }
    
        function parse(numStr) {
            var exponent = 0,
                digits, numberOfIntegerDigits;
            var i, j, zeros;
            if ((numberOfIntegerDigits = numStr.indexOf(DECIMAL_SEP)) > -1) {
                numStr = numStr.replace(DECIMAL_SEP, '');
            }
            if ((i = numStr.search(/e/i)) > 0) {
                if (numberOfIntegerDigits < 0) numberOfIntegerDigits = i;
                numberOfIntegerDigits += +numStr.slice(i + 1);
                numStr = numStr.substring(0, i);
            } else if (numberOfIntegerDigits < 0) {
                numberOfIntegerDigits = numStr.length;
            }
            for (i = 0; numStr.charAt(i) == ZERO_CHAR; i++) {}
            if (i == (zeros = numStr.length)) {
                digits = [0];
                numberOfIntegerDigits = 1;
            } else {
                zeros--;
                while (numStr.charAt(zeros) == ZERO_CHAR) zeros--;
                numberOfIntegerDigits -= i;
                digits = [];
                for (j = 0; i <= zeros; i++, j++) {
                    digits[j] = +numStr.charAt(i);
                }
            }
            if (numberOfIntegerDigits > MAX_DIGITS) {
                digits = digits.splice(0, MAX_DIGITS - 1);
                exponent = numberOfIntegerDigits - 1;
                numberOfIntegerDigits = 1;
            }
            return {
                d: digits,
                e: exponent,
                i: numberOfIntegerDigits
            };
        }
    
        function roundNumber(parsedNumber, fractionSize, minFrac, maxFrac) {
            var digits = parsedNumber.d;
            var fractionLen = digits.length - parsedNumber.i;
            fractionSize = (isUndefined(fractionSize)) ? Math.min(Math.max(minFrac, fractionLen), maxFrac) : +fractionSize;
            var roundAt = fractionSize + parsedNumber.i;
            var digit = digits[roundAt];
            if (roundAt > 0) {
                digits.splice(Math.max(parsedNumber.i, roundAt));
                for (var j = roundAt; j < digits.length; j++) {
                    digits[j] = 0;
                }
            } else {
                fractionLen = Math.max(0, fractionLen);
                parsedNumber.i = 1;
                digits.length = Math.max(1, roundAt = fractionSize + 1);
                digits[0] = 0;
                for (var i = 1; i < roundAt; i++) digits[i] = 0;
            }
            if (digit >= 5) {
                if (roundAt - 1 < 0) {
                    for (var k = 0; k > roundAt; k--) {
                        digits.unshift(0);
                        parsedNumber.i++;
                    }
                    digits.unshift(1);
                    parsedNumber.i++;
                } else {
                    digits[roundAt - 1]++;
                }
            }
            for (; fractionLen < Math.max(0, fractionSize); fractionLen++) digits.push(0);
            var carry = digits.reduceRight(function(carry, d, i, digits) {
                d = d + carry;
                digits[i] = d % 10;
                return Math.floor(d / 10);
            }, 0);
            if (carry) {
                digits.unshift(carry);
                parsedNumber.i++;
            }
        }
    
        function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
            if (!(isString(number) || isNumber(number)) || isNaN(number)) return '';
            var isInfinity = !isFinite(number);
            var isZero = false;
            var numStr = Math.abs(number) + '',
                formattedText = '',
                parsedNumber;
            if (isInfinity) {
                formattedText = '\u221e';
            } else {
                parsedNumber = parse(numStr);
                roundNumber(parsedNumber, fractionSize, pattern.minFrac, pattern.maxFrac);
                var digits = parsedNumber.d;
                var integerLen = parsedNumber.i;
                var exponent = parsedNumber.e;
                var decimals = [];
                isZero = digits.reduce(function(isZero, d) {
                    return isZero && !d;
                }, true);
                while (integerLen < 0) {
                    digits.unshift(0);
                    integerLen++;
                }
                if (integerLen > 0) {
                    decimals = digits.splice(integerLen);
                } else {
                    decimals = digits;
                    digits = [0];
                }
                var groups = [];
                if (digits.length >= pattern.lgSize) {
                    groups.unshift(digits.splice(-pattern.lgSize).join(''));
                }
                while (digits.length > pattern.gSize) {
                    groups.unshift(digits.splice(-pattern.gSize).join(''));
                }
                if (digits.length) {
                    groups.unshift(digits.join(''));
                }
                formattedText = groups.join(groupSep);
                if (decimals.length) {
                    formattedText += decimalSep + decimals.join('');
                }
                if (exponent) {
                    formattedText += 'e+' + exponent;
                }
            }
            if (number < 0 && !isZero) {
                return pattern.negPre + formattedText + pattern.negSuf;
            } else {
                return pattern.posPre + formattedText + pattern.posSuf;
            }
        }
    
        function padNumber(num, digits, trim, negWrap) {
            var neg = '';
            if (num < 0 || (negWrap && num <= 0)) {
                if (negWrap) {
                    num = -num + 1;
                } else {
                    num = -num;
                    neg = '-';
                }
            }
            num = '' + num;
            while (num.length < digits) num = ZERO_CHAR + num;
            if (trim) {
                num = num.substr(num.length - digits);
            }
            return neg + num;
        }
    
        function dateGetter(name, size, offset, trim, negWrap) {
            offset = offset || 0;
            return function(date) {
                var value = date['get' + name]();
                if (offset > 0 || value > -offset) {
                    value += offset;
                }
                if (value === 0 && offset == -12) value = 12;
                return padNumber(value, size, trim, negWrap);
            };
        }
    
        function dateStrGetter(name, shortForm, standAlone) {
            return function(date, formats) {
                var value = date['get' + name]();
                var propPrefix = (standAlone ? 'STANDALONE' : '') + (shortForm ? 'SHORT' : '');
                var get = uppercase(propPrefix + name);
                return formats[get][value];
            };
        }
    
        function timeZoneGetter(date, formats, offset) {
            var zone = -1 * offset;
            var paddedZone = (zone >= 0) ? "+" : "";
            paddedZone += padNumber(Math[zone > 0 ? 'floor' : 'ceil'](zone / 60), 2) +
                padNumber(Math.abs(zone % 60), 2);
            return paddedZone;
        }
    
        function getFirstThursdayOfYear(year) {
            var dayOfWeekOnFirst = (new Date(year, 0, 1)).getDay();
            return new Date(year, 0, ((dayOfWeekOnFirst <= 4) ? 5 : 12) - dayOfWeekOnFirst);
        }
    
        function getThursdayThisWeek(datetime) {
            return new Date(datetime.getFullYear(), datetime.getMonth(),
                datetime.getDate() + (4 - datetime.getDay()));
        }
    
        function weekGetter(size) {
            return function(date) {
                var firstThurs = getFirstThursdayOfYear(date.getFullYear()),
                    thisThurs = getThursdayThisWeek(date);
                var diff = +thisThurs - +firstThurs,
                    result = 1 + Math.round(diff / 6.048e8);
                return padNumber(result, size);
            };
        }
    
        function ampmGetter(date, formats) {
            return date.getHours() < 12 ? formats.AMPMS[0] : formats.AMPMS[1];
        }
    
        function eraGetter(date, formats) {
            return date.getFullYear() <= 0 ? formats.ERAS[0] : formats.ERAS[1];
        }
    
        function longEraGetter(date, formats) {
            return date.getFullYear() <= 0 ? formats.ERANAMES[0] : formats.ERANAMES[1];
        }
        var DATE_FORMATS = {
            yyyy: dateGetter('FullYear', 4, 0, false, true),
            yy: dateGetter('FullYear', 2, 0, true, true),
            y: dateGetter('FullYear', 1, 0, false, true),
            MMMM: dateStrGetter('Month'),
            MMM: dateStrGetter('Month', true),
            MM: dateGetter('Month', 2, 1),
            M: dateGetter('Month', 1, 1),
            LLLL: dateStrGetter('Month', false, true),
            dd: dateGetter('Date', 2),
            d: dateGetter('Date', 1),
            HH: dateGetter('Hours', 2),
            H: dateGetter('Hours', 1),
            hh: dateGetter('Hours', 2, -12),
            h: dateGetter('Hours', 1, -12),
            mm: dateGetter('Minutes', 2),
            m: dateGetter('Minutes', 1),
            ss: dateGetter('Seconds', 2),
            s: dateGetter('Seconds', 1),
            sss: dateGetter('Milliseconds', 3),
            EEEE: dateStrGetter('Day'),
            EEE: dateStrGetter('Day', true),
            a: ampmGetter,
            Z: timeZoneGetter,
            ww: weekGetter(2),
            w: weekGetter(1),
            G: eraGetter,
            GG: eraGetter,
            GGG: eraGetter,
            GGGG: longEraGetter
        };
        var DATE_FORMATS_SPLIT = /((?:[^yMLdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|L+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,
            NUMBER_STRING = /^\-?\d+$/;
        dateFilter.$inject = ['$locale'];
    
        function dateFilter($locale) {
            var R_ISO8601_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;
    
            function jsonStringToDate(string) {
                var match;
                if (match = string.match(R_ISO8601_STR)) {
                    var date = new Date(0),
                        tzHour = 0,
                        tzMin = 0,
                        dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear,
                        timeSetter = match[8] ? date.setUTCHours : date.setHours;
                    if (match[9]) {
                        tzHour = toInt(match[9] + match[10]);
                        tzMin = toInt(match[9] + match[11]);
                    }
                    dateSetter.call(date, toInt(match[1]), toInt(match[2]) - 1, toInt(match[3]));
                    var h = toInt(match[4] || 0) - tzHour;
                    var m = toInt(match[5] || 0) - tzMin;
                    var s = toInt(match[6] || 0);
                    var ms = Math.round(parseFloat('0.' + (match[7] || 0)) * 1000);
                    timeSetter.call(date, h, m, s, ms);
                    return date;
                }
                return string;
            }
            return function(date, format, timezone) {
                var text = '',
                    parts = [],
                    fn, match;
                format = format || 'mediumDate';
                format = $locale.DATETIME_FORMATS[format] || format;
                if (isString(date)) {
                    date = NUMBER_STRING.test(date) ? toInt(date) : jsonStringToDate(date);
                }
                if (isNumber(date)) {
                    date = new Date(date);
                }
                if (!isDate(date) || !isFinite(date.getTime())) {
                    return date;
                }
                while (format) {
                    match = DATE_FORMATS_SPLIT.exec(format);
                    if (match) {
                        parts = concat(parts, match, 1);
                        format = parts.pop();
                    } else {
                        parts.push(format);
                        format = null;
                    }
                }
                var dateTimezoneOffset = date.getTimezoneOffset();
                if (timezone) {
                    dateTimezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
                    date = convertTimezoneToLocal(date, timezone, true);
                }
                forEach(parts, function(value) {
                    fn = DATE_FORMATS[value];
                    text += fn ? fn(date, $locale.DATETIME_FORMATS, dateTimezoneOffset) :
                        value === "''" ? "'" : value.replace(/(^'|'$)/g, '').replace(/''/g, "'");
                });
                return text;
            };
        }
    
        function jsonFilter() {
            return function(object, spacing) {
                if (isUndefined(spacing)) {
                    spacing = 2;
                }
                return toJson(object, spacing);
            };
        }
        var lowercaseFilter = valueFn(lowercase);
        var uppercaseFilter = valueFn(uppercase);
    
        function limitToFilter() {
            return function(input, limit, begin) {
                if (Math.abs(Number(limit)) === Infinity) {
                    limit = Number(limit);
                } else {
                    limit = toInt(limit);
                }
                if (isNaN(limit)) return input;
                if (isNumber(input)) input = input.toString();
                if (!isArray(input) && !isString(input)) return input;
                begin = (!begin || isNaN(begin)) ? 0 : toInt(begin);
                begin = (begin < 0) ? Math.max(0, input.length + begin) : begin;
                if (limit >= 0) {
                    return input.slice(begin, begin + limit);
                } else {
                    if (begin === 0) {
                        return input.slice(limit, input.length);
                    } else {
                        return input.slice(Math.max(0, begin + limit), begin);
                    }
                }
            };
        }
        orderByFilter.$inject = ['$parse'];
    
        function orderByFilter($parse) {
            return function(array, sortPredicate, reverseOrder) {
                if (array == null) return array;
                if (!isArrayLike(array)) {
                    throw minErr('orderBy')('notarray', 'Expected array but received: {0}', array);
                }
                if (!isArray(sortPredicate)) {
                    sortPredicate = [sortPredicate];
                }
                if (sortPredicate.length === 0) {
                    sortPredicate = ['+'];
                }
                var predicates = processPredicates(sortPredicate, reverseOrder);
                predicates.push({
                    get: function() {
                        return {};
                    },
                    descending: reverseOrder ? -1 : 1
                });
                var compareValues = Array.prototype.map.call(array, getComparisonObject);
                compareValues.sort(doComparison);
                array = compareValues.map(function(item) {
                    return item.value;
                });
                return array;
    
                function getComparisonObject(value, index) {
                    return {
                        value: value,
                        predicateValues: predicates.map(function(predicate) {
                            return getPredicateValue(predicate.get(value), index);
                        })
                    };
                }
    
                function doComparison(v1, v2) {
                    var result = 0;
                    for (var index = 0, length = predicates.length; index < length; ++index) {
                        result = compare(v1.predicateValues[index], v2.predicateValues[index]) * predicates[index].descending;
                        if (result) break;
                    }
                    return result;
                }
            };
    
            function processPredicates(sortPredicate, reverseOrder) {
                reverseOrder = reverseOrder ? -1 : 1;
                return sortPredicate.map(function(predicate) {
                    var descending = 1,
                        get = identity;
                    if (isFunction(predicate)) {
                        get = predicate;
                    } else if (isString(predicate)) {
                        if ((predicate.charAt(0) == '+' || predicate.charAt(0) == '-')) {
                            descending = predicate.charAt(0) == '-' ? -1 : 1;
                            predicate = predicate.substring(1);
                        }
                        if (predicate !== '') {
                            get = $parse(predicate);
                            if (get.constant) {
                                var key = get();
                                get = function(value) {
                                    return value[key];
                                };
                            }
                        }
                    }
                    return {
                        get: get,
                        descending: descending * reverseOrder
                    };
                });
            }
    
            function isPrimitive(value) {
                switch (typeof value) {
                    case 'number':
                    case 'boolean':
                    case 'string':
                        return true;
                    default:
                        return false;
                }
            }
    
            function objectValue(value, index) {
                if (typeof value.valueOf === 'function') {
                    value = value.valueOf();
                    if (isPrimitive(value)) return value;
                }
                if (hasCustomToString(value)) {
                    value = value.toString();
                    if (isPrimitive(value)) return value;
                }
                return index;
            }
    
            function getPredicateValue(value, index) {
                var type = typeof value;
                if (value === null) {
                    type = 'string';
                    value = 'null';
                } else if (type === 'string') {
                    value = value.toLowerCase();
                } else if (type === 'object') {
                    value = objectValue(value, index);
                }
                return {
                    value: value,
                    type: type
                };
            }
    
            function compare(v1, v2) {
                var result = 0;
                if (v1.type === v2.type) {
                    if (v1.value !== v2.value) {
                        result = v1.value < v2.value ? -1 : 1;
                    }
                } else {
                    result = v1.type < v2.type ? -1 : 1;
                }
                return result;
            }
        }
    
        function ngDirective(directive) {
            if (isFunction(directive)) {
                directive = {
                    link: directive
                };
            }
            directive.restrict = directive.restrict || 'AC';
            return valueFn(directive);
        }
        var htmlAnchorDirective = valueFn({
            restrict: 'E',
            compile: function(element, attr) {
                if (!attr.href && !attr.xlinkHref) {
                    return function(scope, element) {
                        if (element[0].nodeName.toLowerCase() !== 'a') return;
                        var href = toString.call(element.prop('href')) === '[object SVGAnimatedString]' ?
                            'xlink:href' : 'href';
                        element.on('click', function(event) {
                            if (!element.attr(href)) {
                                event.preventDefault();
                            }
                        });
                    };
                }
            }
        });
        var ngAttributeAliasDirectives = {};
        forEach(BOOLEAN_ATTR, function(propName, attrName) {
            if (propName == "multiple") return;
    
            function defaultLinkFn(scope, element, attr) {
                scope.$watch(attr[normalized], function ngBooleanAttrWatchAction(value) {
                    attr.$set(attrName, !!value);
                });
            }
            var normalized = directiveNormalize('ng-' + attrName);
            var linkFn = defaultLinkFn;
            if (propName === 'checked') {
                linkFn = function(scope, element, attr) {
                    if (attr.ngModel !== attr[normalized]) {
                        defaultLinkFn(scope, element, attr);
                    }
                };
            }
            ngAttributeAliasDirectives[normalized] = function() {
                return {
                    restrict: 'A',
                    priority: 100,
                    link: linkFn
                };
            };
        });
        forEach(ALIASED_ATTR, function(htmlAttr, ngAttr) {
            ngAttributeAliasDirectives[ngAttr] = function() {
                return {
                    priority: 100,
                    link: function(scope, element, attr) {
                        if (ngAttr === "ngPattern" && attr.ngPattern.charAt(0) == "/") {
                            var match = attr.ngPattern.match(REGEX_STRING_REGEXP);
                            if (match) {
                                attr.$set("ngPattern", new RegExp(match[1], match[2]));
                                return;
                            }
                        }
                        scope.$watch(attr[ngAttr], function ngAttrAliasWatchAction(value) {
                            attr.$set(ngAttr, value);
                        });
                    }
                };
            };
        });
        forEach(['src', 'srcset', 'href'], function(attrName) {
            var normalized = directiveNormalize('ng-' + attrName);
            ngAttributeAliasDirectives[normalized] = function() {
                return {
                    priority: 99,
                    link: function(scope, element, attr) {
                        var propName = attrName,
                            name = attrName;
                        if (attrName === 'href' &&
                            toString.call(element.prop('href')) === '[object SVGAnimatedString]') {
                            name = 'xlinkHref';
                            attr.$attr[name] = 'xlink:href';
                            propName = null;
                        }
                        attr.$observe(normalized, function(value) {
                            if (!value) {
                                if (attrName === 'href') {
                                    attr.$set(name, null);
                                }
                                return;
                            }
                            attr.$set(name, value);
                            if (msie && propName) element.prop(propName, attr[name]);
                        });
                    }
                };
            };
        });
        var nullFormCtrl = {
                $addControl: noop,
                $$renameControl: nullFormRenameControl,
                $removeControl: noop,
                $setValidity: noop,
                $setDirty: noop,
                $setPristine: noop,
                $setSubmitted: noop
            },
            SUBMITTED_CLASS = 'ng-submitted';
    
        function nullFormRenameControl(control, name) {
            control.$name = name;
        }
        FormController.$inject = ['$element', '$attrs', '$scope', '$animate', '$interpolate'];
    
        function FormController(element, attrs, $scope, $animate, $interpolate) {
            var form = this,
                controls = [];
            form.$error = {};
            form.$$success = {};
            form.$pending = undefined;
            form.$name = $interpolate(attrs.name || attrs.ngForm || '')($scope);
            form.$dirty = false;
            form.$pristine = true;
            form.$valid = true;
            form.$invalid = false;
            form.$submitted = false;
            form.$$parentForm = nullFormCtrl;
            form.$rollbackViewValue = function() {
                forEach(controls, function(control) {
                    control.$rollbackViewValue();
                });
            };
            form.$commitViewValue = function() {
                forEach(controls, function(control) {
                    control.$commitViewValue();
                });
            };
            form.$addControl = function(control) {
                assertNotHasOwnProperty(control.$name, 'input');
                controls.push(control);
                if (control.$name) {
                    form[control.$name] = control;
                }
                control.$$parentForm = form;
            };
            form.$$renameControl = function(control, newName) {
                var oldName = control.$name;
                if (form[oldName] === control) {
                    delete form[oldName];
                }
                form[newName] = control;
                control.$name = newName;
            };
            form.$removeControl = function(control) {
                if (control.$name && form[control.$name] === control) {
                    delete form[control.$name];
                }
                forEach(form.$pending, function(value, name) {
                    form.$setValidity(name, null, control);
                });
                forEach(form.$error, function(value, name) {
                    form.$setValidity(name, null, control);
                });
                forEach(form.$$success, function(value, name) {
                    form.$setValidity(name, null, control);
                });
                arrayRemove(controls, control);
                control.$$parentForm = nullFormCtrl;
            };
            addSetValidityMethod({
                ctrl: this,
                $element: element,
                set: function(object, property, controller) {
                    var list = object[property];
                    if (!list) {
                        object[property] = [controller];
                    } else {
                        var index = list.indexOf(controller);
                        if (index === -1) {
                            list.push(controller);
                        }
                    }
                },
                unset: function(object, property, controller) {
                    var list = object[property];
                    if (!list) {
                        return;
                    }
                    arrayRemove(list, controller);
                    if (list.length === 0) {
                        delete object[property];
                    }
                },
                $animate: $animate
            });
            form.$setDirty = function() {
                $animate.removeClass(element, PRISTINE_CLASS);
                $animate.addClass(element, DIRTY_CLASS);
                form.$dirty = true;
                form.$pristine = false;
                form.$$parentForm.$setDirty();
            };
            form.$setPristine = function() {
                $animate.setClass(element, PRISTINE_CLASS, DIRTY_CLASS + ' ' + SUBMITTED_CLASS);
                form.$dirty = false;
                form.$pristine = true;
                form.$submitted = false;
                forEach(controls, function(control) {
                    control.$setPristine();
                });
            };
            form.$setUntouched = function() {
                forEach(controls, function(control) {
                    control.$setUntouched();
                });
            };
            form.$setSubmitted = function() {
                $animate.addClass(element, SUBMITTED_CLASS);
                form.$submitted = true;
                form.$$parentForm.$setSubmitted();
            };
        }
        var formDirectiveFactory = function(isNgForm) {
            return ['$timeout', '$parse', function($timeout, $parse) {
                var formDirective = {
                    name: 'form',
                    restrict: isNgForm ? 'EAC' : 'E',
                    require: ['form', '^^?form'],
                    controller: FormController,
                    compile: function ngFormCompile(formElement, attr) {
                        formElement.addClass(PRISTINE_CLASS).addClass(VALID_CLASS);
                        var nameAttr = attr.name ? 'name' : (isNgForm && attr.ngForm ? 'ngForm' : false);
                        return {
                            pre: function ngFormPreLink(scope, formElement, attr, ctrls) {
                                var controller = ctrls[0];
                                if (!('action' in attr)) {
                                    var handleFormSubmission = function(event) {
                                        scope.$apply(function() {
                                            controller.$commitViewValue();
                                            controller.$setSubmitted();
                                        });
                                        event.preventDefault();
                                    };
                                    addEventListenerFn(formElement[0], 'submit', handleFormSubmission);
                                    formElement.on('$destroy', function() {
                                        $timeout(function() {
                                            removeEventListenerFn(formElement[0], 'submit', handleFormSubmission);
                                        }, 0, false);
                                    });
                                }
                                var parentFormCtrl = ctrls[1] || controller.$$parentForm;
                                parentFormCtrl.$addControl(controller);
                                var setter = nameAttr ? getSetter(controller.$name) : noop;
                                if (nameAttr) {
                                    setter(scope, controller);
                                    attr.$observe(nameAttr, function(newValue) {
                                        if (controller.$name === newValue) return;
                                        setter(scope, undefined);
                                        controller.$$parentForm.$$renameControl(controller, newValue);
                                        setter = getSetter(controller.$name);
                                        setter(scope, controller);
                                    });
                                }
                                formElement.on('$destroy', function() {
                                    controller.$$parentForm.$removeControl(controller);
                                    setter(scope, undefined);
                                    extend(controller, nullFormCtrl);
                                });
                            }
                        };
                    }
                };
                return formDirective;
    
                function getSetter(expression) {
                    if (expression === '') {
                        return $parse('this[""]').assign;
                    }
                    return $parse(expression).assign || noop;
                }
            }];
        };
        var formDirective = formDirectiveFactory();
        var ngFormDirective = formDirectiveFactory(true);
        var ISO_DATE_REGEXP = /^\d{4,}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+(?:[+-][0-2]\d:[0-5]\d|Z)$/;
        var URL_REGEXP = /^[a-z][a-z\d.+-]*:\/*(?:[^:@]+(?::[^@]+)?@)?(?:[^\s:/?#]+|\[[a-f\d:]+\])(?::\d+)?(?:\/[^?#]*)?(?:\?[^#]*)?(?:#.*)?$/i;
        var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
        var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/;
        var DATE_REGEXP = /^(\d{4,})-(\d{2})-(\d{2})$/;
        var DATETIMELOCAL_REGEXP = /^(\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
        var WEEK_REGEXP = /^(\d{4,})-W(\d\d)$/;
        var MONTH_REGEXP = /^(\d{4,})-(\d\d)$/;
        var TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
        var PARTIAL_VALIDATION_EVENTS = 'keydown wheel mousedown';
        var PARTIAL_VALIDATION_TYPES = createMap();
        forEach('date,datetime-local,month,time,week'.split(','), function(type) {
            PARTIAL_VALIDATION_TYPES[type] = true;
        });
        var inputType = {
            'text': textInputType,
            'date': createDateInputType('date', DATE_REGEXP,
                createDateParser(DATE_REGEXP, ['yyyy', 'MM', 'dd']),
                'yyyy-MM-dd'),
            'datetime-local': createDateInputType('datetimelocal', DATETIMELOCAL_REGEXP,
                createDateParser(DATETIMELOCAL_REGEXP, ['yyyy', 'MM', 'dd', 'HH', 'mm', 'ss', 'sss']),
                'yyyy-MM-ddTHH:mm:ss.sss'),
            'time': createDateInputType('time', TIME_REGEXP,
                createDateParser(TIME_REGEXP, ['HH', 'mm', 'ss', 'sss']),
                'HH:mm:ss.sss'),
            'week': createDateInputType('week', WEEK_REGEXP, weekParser, 'yyyy-Www'),
            'month': createDateInputType('month', MONTH_REGEXP,
                createDateParser(MONTH_REGEXP, ['yyyy', 'MM']),
                'yyyy-MM'),
            'number': numberInputType,
            'url': urlInputType,
            'email': emailInputType,
            'radio': radioInputType,
            'checkbox': checkboxInputType,
            'hidden': noop,
            'button': noop,
            'submit': noop,
            'reset': noop,
            'file': noop
        };
    
        function stringBasedInputType(ctrl) {
            ctrl.$formatters.push(function(value) {
                return ctrl.$isEmpty(value) ? value : value.toString();
            });
        }
    
        function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
            baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
            stringBasedInputType(ctrl);
        }
    
        function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
            var type = lowercase(element[0].type);
            if (!$sniffer.android) {
                var composing = false;
                element.on('compositionstart', function() {
                    composing = true;
                });
                element.on('compositionend', function() {
                    composing = false;
                    listener();
                });
            }
            var timeout;
            var listener = function(ev) {
                if (timeout) {
                    $browser.defer.cancel(timeout);
                    timeout = null;
                }
                if (composing) return;
                var value = element.val(),
                    event = ev && ev.type;
                if (type !== 'password' && (!attr.ngTrim || attr.ngTrim !== 'false')) {
                    value = trim(value);
                }
                if (ctrl.$viewValue !== value || (value === '' && ctrl.$$hasNativeValidators)) {
                    ctrl.$setViewValue(value, event);
                }
            };
            if ($sniffer.hasEvent('input')) {
                element.on('input', listener);
            } else {
                var deferListener = function(ev, input, origValue) {
                    if (!timeout) {
                        timeout = $browser.defer(function() {
                            timeout = null;
                            if (!input || input.value !== origValue) {
                                listener(ev);
                            }
                        });
                    }
                };
                element.on('keydown', function(event) {
                    var key = event.keyCode;
                    if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return;
                    deferListener(event, this, this.value);
                });
                if ($sniffer.hasEvent('paste')) {
                    element.on('paste cut', deferListener);
                }
            }
            element.on('change', listener);
            if (PARTIAL_VALIDATION_TYPES[type] && ctrl.$$hasNativeValidators && type === attr.type) {
                element.on(PARTIAL_VALIDATION_EVENTS, function(ev) {
                    if (!timeout) {
                        var validity = this[VALIDITY_STATE_PROPERTY];
                        var origBadInput = validity.badInput;
                        var origTypeMismatch = validity.typeMismatch;
                        timeout = $browser.defer(function() {
                            timeout = null;
                            if (validity.badInput !== origBadInput || validity.typeMismatch !== origTypeMismatch) {
                                listener(ev);
                            }
                        });
                    }
                });
            }
            ctrl.$render = function() {
                var value = ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue;
                if (element.val() !== value) {
                    element.val(value);
                }
            };
        }
    
        function weekParser(isoWeek, existingDate) {
            if (isDate(isoWeek)) {
                return isoWeek;
            }
            if (isString(isoWeek)) {
                WEEK_REGEXP.lastIndex = 0;
                var parts = WEEK_REGEXP.exec(isoWeek);
                if (parts) {
                    var year = +parts[1],
                        week = +parts[2],
                        hours = 0,
                        minutes = 0,
                        seconds = 0,
                        milliseconds = 0,
                        firstThurs = getFirstThursdayOfYear(year),
                        addDays = (week - 1) * 7;
                    if (existingDate) {
                        hours = existingDate.getHours();
                        minutes = existingDate.getMinutes();
                        seconds = existingDate.getSeconds();
                        milliseconds = existingDate.getMilliseconds();
                    }
                    return new Date(year, 0, firstThurs.getDate() + addDays, hours, minutes, seconds, milliseconds);
                }
            }
            return NaN;
        }
    
        function createDateParser(regexp, mapping) {
            return function(iso, date) {
                var parts, map;
                if (isDate(iso)) {
                    return iso;
                }
                if (isString(iso)) {
                    if (iso.charAt(0) == '"' && iso.charAt(iso.length - 1) == '"') {
                        iso = iso.substring(1, iso.length - 1);
                    }
                    if (ISO_DATE_REGEXP.test(iso)) {
                        return new Date(iso);
                    }
                    regexp.lastIndex = 0;
                    parts = regexp.exec(iso);
                    if (parts) {
                        parts.shift();
                        if (date) {
                            map = {
                                yyyy: date.getFullYear(),
                                MM: date.getMonth() + 1,
                                dd: date.getDate(),
                                HH: date.getHours(),
                                mm: date.getMinutes(),
                                ss: date.getSeconds(),
                                sss: date.getMilliseconds() / 1000
                            };
                        } else {
                            map = {
                                yyyy: 1970,
                                MM: 1,
                                dd: 1,
                                HH: 0,
                                mm: 0,
                                ss: 0,
                                sss: 0
                            };
                        }
                        forEach(parts, function(part, index) {
                            if (index < mapping.length) {
                                map[mapping[index]] = +part;
                            }
                        });
                        return new Date(map.yyyy, map.MM - 1, map.dd, map.HH, map.mm, map.ss || 0, map.sss * 1000 || 0);
                    }
                }
                return NaN;
            };
        }
    
        function createDateInputType(type, regexp, parseDate, format) {
            return function dynamicDateInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter) {
                badInputChecker(scope, element, attr, ctrl);
                baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
                var timezone = ctrl && ctrl.$options && ctrl.$options.timezone;
                var previousDate;
                ctrl.$$parserName = type;
                ctrl.$parsers.push(function(value) {
                    if (ctrl.$isEmpty(value)) return null;
                    if (regexp.test(value)) {
                        var parsedDate = parseDate(value, previousDate);
                        if (timezone) {
                            parsedDate = convertTimezoneToLocal(parsedDate, timezone);
                        }
                        return parsedDate;
                    }
                    return undefined;
                });
                ctrl.$formatters.push(function(value) {
                    if (value && !isDate(value)) {
                        throw ngModelMinErr('datefmt', 'Expected `{0}` to be a date', value);
                    }
                    if (isValidDate(value)) {
                        previousDate = value;
                        if (previousDate && timezone) {
                            previousDate = convertTimezoneToLocal(previousDate, timezone, true);
                        }
                        return $filter('date')(value, format, timezone);
                    } else {
                        previousDate = null;
                        return '';
                    }
                });
                if (isDefined(attr.min) || attr.ngMin) {
                    var minVal;
                    ctrl.$validators.min = function(value) {
                        return !isValidDate(value) || isUndefined(minVal) || parseDate(value) >= minVal;
                    };
                    attr.$observe('min', function(val) {
                        minVal = parseObservedDateValue(val);
                        ctrl.$validate();
                    });
                }
                if (isDefined(attr.max) || attr.ngMax) {
                    var maxVal;
                    ctrl.$validators.max = function(value) {
                        return !isValidDate(value) || isUndefined(maxVal) || parseDate(value) <= maxVal;
                    };
                    attr.$observe('max', function(val) {
                        maxVal = parseObservedDateValue(val);
                        ctrl.$validate();
                    });
                }
    
                function isValidDate(value) {
                    return value && !(value.getTime && value.getTime() !== value.getTime());
                }
    
                function parseObservedDateValue(val) {
                    return isDefined(val) && !isDate(val) ? parseDate(val) || undefined : val;
                }
            };
        }
    
        function badInputChecker(scope, element, attr, ctrl) {
            var node = element[0];
            var nativeValidation = ctrl.$$hasNativeValidators = isObject(node.validity);
            if (nativeValidation) {
                ctrl.$parsers.push(function(value) {
                    var validity = element.prop(VALIDITY_STATE_PROPERTY) || {};
                    return validity.badInput || validity.typeMismatch ? undefined : value;
                });
            }
        }
    
        function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
            badInputChecker(scope, element, attr, ctrl);
            baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
            ctrl.$$parserName = 'number';
            ctrl.$parsers.push(function(value) {
                if (ctrl.$isEmpty(value)) return null;
                if (NUMBER_REGEXP.test(value)) return parseFloat(value);
                return undefined;
            });
            ctrl.$formatters.push(function(value) {
                if (!ctrl.$isEmpty(value)) {
                    if (!isNumber(value)) {
                        throw ngModelMinErr('numfmt', 'Expected `{0}` to be a number', value);
                    }
                    value = value.toString();
                }
                return value;
            });
            if (isDefined(attr.min) || attr.ngMin) {
                var minVal;
                ctrl.$validators.min = function(value) {
                    return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal;
                };
                attr.$observe('min', function(val) {
                    if (isDefined(val) && !isNumber(val)) {
                        val = parseFloat(val, 10);
                    }
                    minVal = isNumber(val) && !isNaN(val) ? val : undefined;
                    ctrl.$validate();
                });
            }
            if (isDefined(attr.max) || attr.ngMax) {
                var maxVal;
                ctrl.$validators.max = function(value) {
                    return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal;
                };
                attr.$observe('max', function(val) {
                    if (isDefined(val) && !isNumber(val)) {
                        val = parseFloat(val, 10);
                    }
                    maxVal = isNumber(val) && !isNaN(val) ? val : undefined;
                    ctrl.$validate();
                });
            }
        }
    
        function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) {
            baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
            stringBasedInputType(ctrl);
            ctrl.$$parserName = 'url';
            ctrl.$validators.url = function(modelValue, viewValue) {
                var value = modelValue || viewValue;
                return ctrl.$isEmpty(value) || URL_REGEXP.test(value);
            };
        }
    
        function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) {
            baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
            stringBasedInputType(ctrl);
            ctrl.$$parserName = 'email';
            ctrl.$validators.email = function(modelValue, viewValue) {
                var value = modelValue || viewValue;
                return ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value);
            };
        }
    
        function radioInputType(scope, element, attr, ctrl) {
            if (isUndefined(attr.name)) {
                element.attr('name', nextUid());
            }
            var listener = function(ev) {
                if (element[0].checked) {
                    ctrl.$setViewValue(attr.value, ev && ev.type);
                }
            };
            element.on('click', listener);
            ctrl.$render = function() {
                var value = attr.value;
                element[0].checked = (value == ctrl.$viewValue);
            };
            attr.$observe('value', ctrl.$render);
        }
    
        function parseConstantExpr($parse, context, name, expression, fallback) {
            var parseFn;
            if (isDefined(expression)) {
                parseFn = $parse(expression);
                if (!parseFn.constant) {
                    throw ngModelMinErr('constexpr', 'Expected constant expression for `{0}`, but saw ' +
                        '`{1}`.', name, expression);
                }
                return parseFn(context);
            }
            return fallback;
        }
    
        function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter, $parse) {
            var trueValue = parseConstantExpr($parse, scope, 'ngTrueValue', attr.ngTrueValue, true);
            var falseValue = parseConstantExpr($parse, scope, 'ngFalseValue', attr.ngFalseValue, false);
            var listener = function(ev) {
                ctrl.$setViewValue(element[0].checked, ev && ev.type);
            };
            element.on('click', listener);
            ctrl.$render = function() {
                element[0].checked = ctrl.$viewValue;
            };
            ctrl.$isEmpty = function(value) {
                return value === false;
            };
            ctrl.$formatters.push(function(value) {
                return equals(value, trueValue);
            });
            ctrl.$parsers.push(function(value) {
                return value ? trueValue : falseValue;
            });
        }
        var inputDirective = ['$browser', '$sniffer', '$filter', '$parse',
            function($browser, $sniffer, $filter, $parse) {
                return {
                    restrict: 'E',
                    require: ['?ngModel'],
                    link: {
                        pre: function(scope, element, attr, ctrls) {
                            if (ctrls[0]) {
                                (inputType[lowercase(attr.type)] || inputType.text)(scope, element, attr, ctrls[0], $sniffer,
                                    $browser, $filter, $parse);
                            }
                        }
                    }
                };
            }
        ];
        var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
        var ngValueDirective = function() {
            return {
                restrict: 'A',
                priority: 100,
                compile: function(tpl, tplAttr) {
                    if (CONSTANT_VALUE_REGEXP.test(tplAttr.ngValue)) {
                        return function ngValueConstantLink(scope, elm, attr) {
                            attr.$set('value', scope.$eval(attr.ngValue));
                        };
                    } else {
                        return function ngValueLink(scope, elm, attr) {
                            scope.$watch(attr.ngValue, function valueWatchAction(value) {
                                attr.$set('value', value);
                            });
                        };
                    }
                }
            };
        };
        var ngBindDirective = ['$compile', function($compile) {
            return {
                restrict: 'AC',
                compile: function ngBindCompile(templateElement) {
                    $compile.$$addBindingClass(templateElement);
                    return function ngBindLink(scope, element, attr) {
                        $compile.$$addBindingInfo(element, attr.ngBind);
                        element = element[0];
                        scope.$watch(attr.ngBind, function ngBindWatchAction(value) {
                            element.textContent = isUndefined(value) ? '' : value;
                        });
                    };
                }
            };
        }];
        var ngBindTemplateDirective = ['$interpolate', '$compile', function($interpolate, $compile) {
            return {
                compile: function ngBindTemplateCompile(templateElement) {
                    $compile.$$addBindingClass(templateElement);
                    return function ngBindTemplateLink(scope, element, attr) {
                        var interpolateFn = $interpolate(element.attr(attr.$attr.ngBindTemplate));
                        $compile.$$addBindingInfo(element, interpolateFn.expressions);
                        element = element[0];
                        attr.$observe('ngBindTemplate', function(value) {
                            element.textContent = isUndefined(value) ? '' : value;
                        });
                    };
                }
            };
        }];
        var ngBindHtmlDirective = ['$sce', '$parse', '$compile', function($sce, $parse, $compile) {
            return {
                restrict: 'A',
                compile: function ngBindHtmlCompile(tElement, tAttrs) {
                    var ngBindHtmlGetter = $parse(tAttrs.ngBindHtml);
                    var ngBindHtmlWatch = $parse(tAttrs.ngBindHtml, function getStringValue(value) {
                        return (value || '').toString();
                    });
                    $compile.$$addBindingClass(tElement);
                    return function ngBindHtmlLink(scope, element, attr) {
                        $compile.$$addBindingInfo(element, attr.ngBindHtml);
                        scope.$watch(ngBindHtmlWatch, function ngBindHtmlWatchAction() {
                            element.html($sce.getTrustedHtml(ngBindHtmlGetter(scope)) || '');
                        });
                    };
                }
            };
        }];
        var ngChangeDirective = valueFn({
            restrict: 'A',
            require: 'ngModel',
            link: function(scope, element, attr, ctrl) {
                ctrl.$viewChangeListeners.push(function() {
                    scope.$eval(attr.ngChange);
                });
            }
        });
    
        function classDirective(name, selector) {
            name = 'ngClass' + name;
            return ['$animate', function($animate) {
                return {
                    restrict: 'AC',
                    link: function(scope, element, attr) {
                        var oldVal;
                        scope.$watch(attr[name], ngClassWatchAction, true);
                        attr.$observe('class', function(value) {
                            ngClassWatchAction(scope.$eval(attr[name]));
                        });
                        if (name !== 'ngClass') {
                            scope.$watch('$index', function($index, old$index) {
                                var mod = $index & 1;
                                if (mod !== (old$index & 1)) {
                                    var classes = arrayClasses(scope.$eval(attr[name]));
                                    mod === selector ?
                                        addClasses(classes) :
                                        removeClasses(classes);
                                }
                            });
                        }
    
                        function addClasses(classes) {
                            var newClasses = digestClassCounts(classes, 1);
                            attr.$addClass(newClasses);
                        }
    
                        function removeClasses(classes) {
                            var newClasses = digestClassCounts(classes, -1);
                            attr.$removeClass(newClasses);
                        }
    
                        function digestClassCounts(classes, count) {
                            var classCounts = element.data('$classCounts') || createMap();
                            var classesToUpdate = [];
                            forEach(classes, function(className) {
                                if (count > 0 || classCounts[className]) {
                                    classCounts[className] = (classCounts[className] || 0) + count;
                                    if (classCounts[className] === +(count > 0)) {
                                        classesToUpdate.push(className);
                                    }
                                }
                            });
                            element.data('$classCounts', classCounts);
                            return classesToUpdate.join(' ');
                        }
    
                        function updateClasses(oldClasses, newClasses) {
                            var toAdd = arrayDifference(newClasses, oldClasses);
                            var toRemove = arrayDifference(oldClasses, newClasses);
                            toAdd = digestClassCounts(toAdd, 1);
                            toRemove = digestClassCounts(toRemove, -1);
                            if (toAdd && toAdd.length) {
                                $animate.addClass(element, toAdd);
                            }
                            if (toRemove && toRemove.length) {
                                $animate.removeClass(element, toRemove);
                            }
                        }
    
                        function ngClassWatchAction(newVal) {
                            if (selector === true || scope.$index % 2 === selector) {
                                var newClasses = arrayClasses(newVal || []);
                                if (!oldVal) {
                                    addClasses(newClasses);
                                } else if (!equals(newVal, oldVal)) {
                                    var oldClasses = arrayClasses(oldVal);
                                    updateClasses(oldClasses, newClasses);
                                }
                            }
                            oldVal = shallowCopy(newVal);
                        }
                    }
                };
    
                function arrayDifference(tokens1, tokens2) {
                    var values = [];
                    outer:
                        for (var i = 0; i < tokens1.length; i++) {
                            var token = tokens1[i];
                            for (var j = 0; j < tokens2.length; j++) {
                                if (token == tokens2[j]) continue outer;
                            }
                            values.push(token);
                        }
                    return values;
                }
    
                function arrayClasses(classVal) {
                    var classes = [];
                    if (isArray(classVal)) {
                        forEach(classVal, function(v) {
                            classes = classes.concat(arrayClasses(v));
                        });
                        return classes;
                    } else if (isString(classVal)) {
                        return classVal.split(' ');
                    } else if (isObject(classVal)) {
                        forEach(classVal, function(v, k) {
                            if (v) {
                                classes = classes.concat(k.split(' '));
                            }
                        });
                        return classes;
                    }
                    return classVal;
                }
            }];
        }
        var ngClassDirective = classDirective('', true);
        var ngClassOddDirective = classDirective('Odd', 0);
        var ngClassEvenDirective = classDirective('Even', 1);
        var ngCloakDirective = ngDirective({
            compile: function(element, attr) {
                attr.$set('ngCloak', undefined);
                element.removeClass('ng-cloak');
            }
        });
        var ngControllerDirective = [function() {
            return {
                restrict: 'A',
                scope: true,
                controller: '@',
                priority: 500
            };
        }];
        var ngEventDirectives = {};
        var forceAsyncEvents = {
            'blur': true,
            'focus': true
        };
        forEach(
            'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '),
            function(eventName) {
                var directiveName = directiveNormalize('ng-' + eventName);
                ngEventDirectives[directiveName] = ['$parse', '$rootScope', function($parse, $rootScope) {
                    return {
                        restrict: 'A',
                        compile: function($element, attr) {
                            var fn = $parse(attr[directiveName], null, true);
                            return function ngEventHandler(scope, element) {
                                element.on(eventName, function(event) {
                                    var callback = function() {
                                        fn(scope, {
                                            $event: event
                                        });
                                    };
                                    if (forceAsyncEvents[eventName] && $rootScope.$$phase) {
                                        scope.$evalAsync(callback);
                                    } else {
                                        scope.$apply(callback);
                                    }
                                });
                            };
                        }
                    };
                }];
            }
        );
        var ngIfDirective = ['$animate', '$compile', function($animate, $compile) {
            return {
                multiElement: true,
                transclude: 'element',
                priority: 600,
                terminal: true,
                restrict: 'A',
                $$tlb: true,
                link: function($scope, $element, $attr, ctrl, $transclude) {
                    var block, childScope, previousElements;
                    $scope.$watch($attr.ngIf, function ngIfWatchAction(value) {
                        if (value) {
                            if (!childScope) {
                                $transclude(function(clone, newScope) {
                                    childScope = newScope;
                                    clone[clone.length++] = $compile.$$createComment('end ngIf', $attr.ngIf);
                                    block = {
                                        clone: clone
                                    };
                                    $animate.enter(clone, $element.parent(), $element);
                                });
                            }
                        } else {
                            if (previousElements) {
                                previousElements.remove();
                                previousElements = null;
                            }
                            if (childScope) {
                                childScope.$destroy();
                                childScope = null;
                            }
                            if (block) {
                                previousElements = getBlockNodes(block.clone);
                                $animate.leave(previousElements).then(function() {
                                    previousElements = null;
                                });
                                block = null;
                            }
                        }
                    });
                }
            };
        }];
        var ngIncludeDirective = ['$templateRequest', '$anchorScroll', '$animate',
            function($templateRequest, $anchorScroll, $animate) {
                return {
                    restrict: 'ECA',
                    priority: 400,
                    terminal: true,
                    transclude: 'element',
                    controller: angular.noop,
                    compile: function(element, attr) {
                        var srcExp = attr.ngInclude || attr.src,
                            onloadExp = attr.onload || '',
                            autoScrollExp = attr.autoscroll;
                        return function(scope, $element, $attr, ctrl, $transclude) {
                            var changeCounter = 0,
                                currentScope,
                                previousElement,
                                currentElement;
                            var cleanupLastIncludeContent = function() {
                                if (previousElement) {
                                    previousElement.remove();
                                    previousElement = null;
                                }
                                if (currentScope) {
                                    currentScope.$destroy();
                                    currentScope = null;
                                }
                                if (currentElement) {
                                    $animate.leave(currentElement).then(function() {
                                        previousElement = null;
                                    });
                                    previousElement = currentElement;
                                    currentElement = null;
                                }
                            };
                            scope.$watch(srcExp, function ngIncludeWatchAction(src) {
                                var afterAnimation = function() {
                                    if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) {
                                        $anchorScroll();
                                    }
                                };
                                var thisChangeId = ++changeCounter;
                                if (src) {
                                    $templateRequest(src, true).then(function(response) {
                                        if (scope.$$destroyed) return;
                                        if (thisChangeId !== changeCounter) return;
                                        var newScope = scope.$new();
                                        ctrl.template = response;
                                        var clone = $transclude(newScope, function(clone) {
                                            cleanupLastIncludeContent();
                                            $animate.enter(clone, null, $element).then(afterAnimation);
                                        });
                                        currentScope = newScope;
                                        currentElement = clone;
                                        currentScope.$emit('$includeContentLoaded', src);
                                        scope.$eval(onloadExp);
                                    }, function() {
                                        if (scope.$$destroyed) return;
                                        if (thisChangeId === changeCounter) {
                                            cleanupLastIncludeContent();
                                            scope.$emit('$includeContentError', src);
                                        }
                                    });
                                    scope.$emit('$includeContentRequested', src);
                                } else {
                                    cleanupLastIncludeContent();
                                    ctrl.template = null;
                                }
                            });
                        };
                    }
                };
            }
        ];
        var ngIncludeFillContentDirective = ['$compile',
            function($compile) {
                return {
                    restrict: 'ECA',
                    priority: -400,
                    require: 'ngInclude',
                    link: function(scope, $element, $attr, ctrl) {
                        if (toString.call($element[0]).match(/SVG/)) {
                            $element.empty();
                            $compile(jqLiteBuildFragment(ctrl.template, document).childNodes)(scope,
                                function namespaceAdaptedClone(clone) {
                                    $element.append(clone);
                                }, {
                                    futureParentElement: $element
                                });
                            return;
                        }
                        $element.html(ctrl.template);
                        $compile($element.contents())(scope);
                    }
                };
            }
        ];
        var ngInitDirective = ngDirective({
            priority: 450,
            compile: function() {
                return {
                    pre: function(scope, element, attrs) {
                        scope.$eval(attrs.ngInit);
                    }
                };
            }
        });
        var ngListDirective = function() {
            return {
                restrict: 'A',
                priority: 100,
                require: 'ngModel',
                link: function(scope, element, attr, ctrl) {
                    var ngList = element.attr(attr.$attr.ngList) || ', ';
                    var trimValues = attr.ngTrim !== 'false';
                    var separator = trimValues ? trim(ngList) : ngList;
                    var parse = function(viewValue) {
                        if (isUndefined(viewValue)) return;
                        var list = [];
                        if (viewValue) {
                            forEach(viewValue.split(separator), function(value) {
                                if (value) list.push(trimValues ? trim(value) : value);
                            });
                        }
                        return list;
                    };
                    ctrl.$parsers.push(parse);
                    ctrl.$formatters.push(function(value) {
                        if (isArray(value)) {
                            return value.join(ngList);
                        }
                        return undefined;
                    });
                    ctrl.$isEmpty = function(value) {
                        return !value || !value.length;
                    };
                }
            };
        };
        var VALID_CLASS = 'ng-valid',
            INVALID_CLASS = 'ng-invalid',
            PRISTINE_CLASS = 'ng-pristine',
            DIRTY_CLASS = 'ng-dirty',
            UNTOUCHED_CLASS = 'ng-untouched',
            TOUCHED_CLASS = 'ng-touched',
            PENDING_CLASS = 'ng-pending',
            EMPTY_CLASS = 'ng-empty',
            NOT_EMPTY_CLASS = 'ng-not-empty';
        var ngModelMinErr = minErr('ngModel');
        var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$parse', '$animate', '$timeout', '$rootScope', '$q', '$interpolate',
            function($scope, $exceptionHandler, $attr, $element, $parse, $animate, $timeout, $rootScope, $q, $interpolate) {
                this.$viewValue = Number.NaN;
                this.$modelValue = Number.NaN;
                this.$$rawModelValue = undefined;
                this.$validators = {};
                this.$asyncValidators = {};
                this.$parsers = [];
                this.$formatters = [];
                this.$viewChangeListeners = [];
                this.$untouched = true;
                this.$touched = false;
                this.$pristine = true;
                this.$dirty = false;
                this.$valid = true;
                this.$invalid = false;
                this.$error = {};
                this.$$success = {};
                this.$pending = undefined;
                this.$name = $interpolate($attr.name || '', false)($scope);
                this.$$parentForm = nullFormCtrl;
                var parsedNgModel = $parse($attr.ngModel),
                    parsedNgModelAssign = parsedNgModel.assign,
                    ngModelGet = parsedNgModel,
                    ngModelSet = parsedNgModelAssign,
                    pendingDebounce = null,
                    parserValid,
                    ctrl = this;
                this.$$setOptions = function(options) {
                    ctrl.$options = options;
                    if (options && options.getterSetter) {
                        var invokeModelGetter = $parse($attr.ngModel + '()'),
                            invokeModelSetter = $parse($attr.ngModel + '($$$p)');
                        ngModelGet = function($scope) {
                            var modelValue = parsedNgModel($scope);
                            if (isFunction(modelValue)) {
                                modelValue = invokeModelGetter($scope);
                            }
                            return modelValue;
                        };
                        ngModelSet = function($scope, newValue) {
                            if (isFunction(parsedNgModel($scope))) {
                                invokeModelSetter($scope, {
                                    $$$p: newValue
                                });
                            } else {
                                parsedNgModelAssign($scope, newValue);
                            }
                        };
                    } else if (!parsedNgModel.assign) {
                        throw ngModelMinErr('nonassign', "Expression '{0}' is non-assignable. Element: {1}",
                            $attr.ngModel, startingTag($element));
                    }
                };
                this.$render = noop;
                this.$isEmpty = function(value) {
                    return isUndefined(value) || value === '' || value === null || value !== value;
                };
                this.$$updateEmptyClasses = function(value) {
                    if (ctrl.$isEmpty(value)) {
                        $animate.removeClass($element, NOT_EMPTY_CLASS);
                        $animate.addClass($element, EMPTY_CLASS);
                    } else {
                        $animate.removeClass($element, EMPTY_CLASS);
                        $animate.addClass($element, NOT_EMPTY_CLASS);
                    }
                };
                var currentValidationRunId = 0;
                addSetValidityMethod({
                    ctrl: this,
                    $element: $element,
                    set: function(object, property) {
                        object[property] = true;
                    },
                    unset: function(object, property) {
                        delete object[property];
                    },
                    $animate: $animate
                });
                this.$setPristine = function() {
                    ctrl.$dirty = false;
                    ctrl.$pristine = true;
                    $animate.removeClass($element, DIRTY_CLASS);
                    $animate.addClass($element, PRISTINE_CLASS);
                };
                this.$setDirty = function() {
                    ctrl.$dirty = true;
                    ctrl.$pristine = false;
                    $animate.removeClass($element, PRISTINE_CLASS);
                    $animate.addClass($element, DIRTY_CLASS);
                    ctrl.$$parentForm.$setDirty();
                };
                this.$setUntouched = function() {
                    ctrl.$touched = false;
                    ctrl.$untouched = true;
                    $animate.setClass($element, UNTOUCHED_CLASS, TOUCHED_CLASS);
                };
                this.$setTouched = function() {
                    ctrl.$touched = true;
                    ctrl.$untouched = false;
                    $animate.setClass($element, TOUCHED_CLASS, UNTOUCHED_CLASS);
                };
                this.$rollbackViewValue = function() {
                    $timeout.cancel(pendingDebounce);
                    ctrl.$viewValue = ctrl.$$lastCommittedViewValue;
                    ctrl.$render();
                };
                this.$validate = function() {
                    if (isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue)) {
                        return;
                    }
                    var viewValue = ctrl.$$lastCommittedViewValue;
                    var modelValue = ctrl.$$rawModelValue;
                    var prevValid = ctrl.$valid;
                    var prevModelValue = ctrl.$modelValue;
                    var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid;
                    ctrl.$$runValidators(modelValue, viewValue, function(allValid) {
                        if (!allowInvalid && prevValid !== allValid) {
                            ctrl.$modelValue = allValid ? modelValue : undefined;
                            if (ctrl.$modelValue !== prevModelValue) {
                                ctrl.$$writeModelToScope();
                            }
                        }
                    });
                };
                this.$$runValidators = function(modelValue, viewValue, doneCallback) {
                    currentValidationRunId++;
                    var localValidationRunId = currentValidationRunId;
                    if (!processParseErrors()) {
                        validationDone(false);
                        return;
                    }
                    if (!processSyncValidators()) {
                        validationDone(false);
                        return;
                    }
                    processAsyncValidators();
    
                    function processParseErrors() {
                        var errorKey = ctrl.$$parserName || 'parse';
                        if (isUndefined(parserValid)) {
                            setValidity(errorKey, null);
                        } else {
                            if (!parserValid) {
                                forEach(ctrl.$validators, function(v, name) {
                                    setValidity(name, null);
                                });
                                forEach(ctrl.$asyncValidators, function(v, name) {
                                    setValidity(name, null);
                                });
                            }
                            setValidity(errorKey, parserValid);
                            return parserValid;
                        }
                        return true;
                    }
    
                    function processSyncValidators() {
                        var syncValidatorsValid = true;
                        forEach(ctrl.$validators, function(validator, name) {
                            var result = validator(modelValue, viewValue);
                            syncValidatorsValid = syncValidatorsValid && result;
                            setValidity(name, result);
                        });
                        if (!syncValidatorsValid) {
                            forEach(ctrl.$asyncValidators, function(v, name) {
                                setValidity(name, null);
                            });
                            return false;
                        }
                        return true;
                    }
    
                    function processAsyncValidators() {
                        var validatorPromises = [];
                        var allValid = true;
                        forEach(ctrl.$asyncValidators, function(validator, name) {
                            var promise = validator(modelValue, viewValue);
                            if (!isPromiseLike(promise)) {
                                throw ngModelMinErr('nopromise',
                                    "Expected asynchronous validator to return a promise but got '{0}' instead.", promise);
                            }
                            setValidity(name, undefined);
                            validatorPromises.push(promise.then(function() {
                                setValidity(name, true);
                            }, function() {
                                allValid = false;
                                setValidity(name, false);
                            }));
                        });
                        if (!validatorPromises.length) {
                            validationDone(true);
                        } else {
                            $q.all(validatorPromises).then(function() {
                                validationDone(allValid);
                            }, noop);
                        }
                    }
    
                    function setValidity(name, isValid) {
                        if (localValidationRunId === currentValidationRunId) {
                            ctrl.$setValidity(name, isValid);
                        }
                    }
    
                    function validationDone(allValid) {
                        if (localValidationRunId === currentValidationRunId) {
                            doneCallback(allValid);
                        }
                    }
                };
                this.$commitViewValue = function() {
                    var viewValue = ctrl.$viewValue;
                    $timeout.cancel(pendingDebounce);
                    if (ctrl.$$lastCommittedViewValue === viewValue && (viewValue !== '' || !ctrl.$$hasNativeValidators)) {
                        return;
                    }
                    ctrl.$$updateEmptyClasses(viewValue);
                    ctrl.$$lastCommittedViewValue = viewValue;
                    if (ctrl.$pristine) {
                        this.$setDirty();
                    }
                    this.$$parseAndValidate();
                };
                this.$$parseAndValidate = function() {
                    var viewValue = ctrl.$$lastCommittedViewValue;
                    var modelValue = viewValue;
                    parserValid = isUndefined(modelValue) ? undefined : true;
                    if (parserValid) {
                        for (var i = 0; i < ctrl.$parsers.length; i++) {
                            modelValue = ctrl.$parsers[i](modelValue);
                            if (isUndefined(modelValue)) {
                                parserValid = false;
                                break;
                            }
                        }
                    }
                    if (isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue)) {
                        ctrl.$modelValue = ngModelGet($scope);
                    }
                    var prevModelValue = ctrl.$modelValue;
                    var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid;
                    ctrl.$$rawModelValue = modelValue;
                    if (allowInvalid) {
                        ctrl.$modelValue = modelValue;
                        writeToModelIfNeeded();
                    }
                    ctrl.$$runValidators(modelValue, ctrl.$$lastCommittedViewValue, function(allValid) {
                        if (!allowInvalid) {
                            ctrl.$modelValue = allValid ? modelValue : undefined;
                            writeToModelIfNeeded();
                        }
                    });
    
                    function writeToModelIfNeeded() {
                        if (ctrl.$modelValue !== prevModelValue) {
                            ctrl.$$writeModelToScope();
                        }
                    }
                };
                this.$$writeModelToScope = function() {
                    ngModelSet($scope, ctrl.$modelValue);
                    forEach(ctrl.$viewChangeListeners, function(listener) {
                        try {
                            listener();
                        } catch (e) {
                            $exceptionHandler(e);
                        }
                    });
                };
                this.$setViewValue = function(value, trigger) {
                    ctrl.$viewValue = value;
                    if (!ctrl.$options || ctrl.$options.updateOnDefault) {
                        ctrl.$$debounceViewValueCommit(trigger);
                    }
                };
                this.$$debounceViewValueCommit = function(trigger) {
                    var debounceDelay = 0,
                        options = ctrl.$options,
                        debounce;
                    if (options && isDefined(options.debounce)) {
                        debounce = options.debounce;
                        if (isNumber(debounce)) {
                            debounceDelay = debounce;
                        } else if (isNumber(debounce[trigger])) {
                            debounceDelay = debounce[trigger];
                        } else if (isNumber(debounce['default'])) {
                            debounceDelay = debounce['default'];
                        }
                    }
                    $timeout.cancel(pendingDebounce);
                    if (debounceDelay) {
                        pendingDebounce = $timeout(function() {
                            ctrl.$commitViewValue();
                        }, debounceDelay);
                    } else if ($rootScope.$$phase) {
                        ctrl.$commitViewValue();
                    } else {
                        $scope.$apply(function() {
                            ctrl.$commitViewValue();
                        });
                    }
                };
                $scope.$watch(function ngModelWatch() {
                    var modelValue = ngModelGet($scope);
                    if (modelValue !== ctrl.$modelValue &&
                        (ctrl.$modelValue === ctrl.$modelValue || modelValue === modelValue)
                    ) {
                        ctrl.$modelValue = ctrl.$$rawModelValue = modelValue;
                        parserValid = undefined;
                        var formatters = ctrl.$formatters,
                            idx = formatters.length;
                        var viewValue = modelValue;
                        while (idx--) {
                            viewValue = formatters[idx](viewValue);
                        }
                        if (ctrl.$viewValue !== viewValue) {
                            ctrl.$$updateEmptyClasses(viewValue);
                            ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;
                            ctrl.$render();
                            ctrl.$$runValidators(modelValue, viewValue, noop);
                        }
                    }
                    return modelValue;
                });
            }
        ];
        var ngModelDirective = ['$rootScope', function($rootScope) {
            return {
                restrict: 'A',
                require: ['ngModel', '^?form', '^?ngModelOptions'],
                controller: NgModelController,
                priority: 1,
                compile: function ngModelCompile(element) {
                    element.addClass(PRISTINE_CLASS).addClass(UNTOUCHED_CLASS).addClass(VALID_CLASS);
                    return {
                        pre: function ngModelPreLink(scope, element, attr, ctrls) {
                            var modelCtrl = ctrls[0],
                                formCtrl = ctrls[1] || modelCtrl.$$parentForm;
                            modelCtrl.$$setOptions(ctrls[2] && ctrls[2].$options);
                            formCtrl.$addControl(modelCtrl);
                            attr.$observe('name', function(newValue) {
                                if (modelCtrl.$name !== newValue) {
                                    modelCtrl.$$parentForm.$$renameControl(modelCtrl, newValue);
                                }
                            });
                            scope.$on('$destroy', function() {
                                modelCtrl.$$parentForm.$removeControl(modelCtrl);
                            });
                        },
                        post: function ngModelPostLink(scope, element, attr, ctrls) {
                            var modelCtrl = ctrls[0];
                            if (modelCtrl.$options && modelCtrl.$options.updateOn) {
                                element.on(modelCtrl.$options.updateOn, function(ev) {
                                    modelCtrl.$$debounceViewValueCommit(ev && ev.type);
                                });
                            }
                            element.on('blur', function() {
                                if (modelCtrl.$touched) return;
                                if ($rootScope.$$phase) {
                                    scope.$evalAsync(modelCtrl.$setTouched);
                                } else {
                                    scope.$apply(modelCtrl.$setTouched);
                                }
                            });
                        }
                    };
                }
            };
        }];
        var DEFAULT_REGEXP = /(\s+|^)default(\s+|$)/;
        var ngModelOptionsDirective = function() {
            return {
                restrict: 'A',
                controller: ['$scope', '$attrs', function($scope, $attrs) {
                    var that = this;
                    this.$options = copy($scope.$eval($attrs.ngModelOptions));
                    if (isDefined(this.$options.updateOn)) {
                        this.$options.updateOnDefault = false;
                        this.$options.updateOn = trim(this.$options.updateOn.replace(DEFAULT_REGEXP, function() {
                            that.$options.updateOnDefault = true;
                            return ' ';
                        }));
                    } else {
                        this.$options.updateOnDefault = true;
                    }
                }]
            };
        };
    
        function addSetValidityMethod(context) {
            var ctrl = context.ctrl,
                $element = context.$element,
                classCache = {},
                set = context.set,
                unset = context.unset,
                $animate = context.$animate;
            classCache[INVALID_CLASS] = !(classCache[VALID_CLASS] = $element.hasClass(VALID_CLASS));
            ctrl.$setValidity = setValidity;
    
            function setValidity(validationErrorKey, state, controller) {
                if (isUndefined(state)) {
                    createAndSet('$pending', validationErrorKey, controller);
                } else {
                    unsetAndCleanup('$pending', validationErrorKey, controller);
                }
                if (!isBoolean(state)) {
                    unset(ctrl.$error, validationErrorKey, controller);
                    unset(ctrl.$$success, validationErrorKey, controller);
                } else {
                    if (state) {
                        unset(ctrl.$error, validationErrorKey, controller);
                        set(ctrl.$$success, validationErrorKey, controller);
                    } else {
                        set(ctrl.$error, validationErrorKey, controller);
                        unset(ctrl.$$success, validationErrorKey, controller);
                    }
                }
                if (ctrl.$pending) {
                    cachedToggleClass(PENDING_CLASS, true);
                    ctrl.$valid = ctrl.$invalid = undefined;
                    toggleValidationCss('', null);
                } else {
                    cachedToggleClass(PENDING_CLASS, false);
                    ctrl.$valid = isObjectEmpty(ctrl.$error);
                    ctrl.$invalid = !ctrl.$valid;
                    toggleValidationCss('', ctrl.$valid);
                }
                var combinedState;
                if (ctrl.$pending && ctrl.$pending[validationErrorKey]) {
                    combinedState = undefined;
                } else if (ctrl.$error[validationErrorKey]) {
                    combinedState = false;
                } else if (ctrl.$$success[validationErrorKey]) {
                    combinedState = true;
                } else {
                    combinedState = null;
                }
                toggleValidationCss(validationErrorKey, combinedState);
                ctrl.$$parentForm.$setValidity(validationErrorKey, combinedState, ctrl);
            }
    
            function createAndSet(name, value, controller) {
                if (!ctrl[name]) {
                    ctrl[name] = {};
                }
                set(ctrl[name], value, controller);
            }
    
            function unsetAndCleanup(name, value, controller) {
                if (ctrl[name]) {
                    unset(ctrl[name], value, controller);
                }
                if (isObjectEmpty(ctrl[name])) {
                    ctrl[name] = undefined;
                }
            }
    
            function cachedToggleClass(className, switchValue) {
                if (switchValue && !classCache[className]) {
                    $animate.addClass($element, className);
                    classCache[className] = true;
                } else if (!switchValue && classCache[className]) {
                    $animate.removeClass($element, className);
                    classCache[className] = false;
                }
            }
    
            function toggleValidationCss(validationErrorKey, isValid) {
                validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : '';
                cachedToggleClass(VALID_CLASS + validationErrorKey, isValid === true);
                cachedToggleClass(INVALID_CLASS + validationErrorKey, isValid === false);
            }
        }
    
        function isObjectEmpty(obj) {
            if (obj) {
                for (var prop in obj) {
                    if (obj.hasOwnProperty(prop)) {
                        return false;
                    }
                }
            }
            return true;
        }
        var ngNonBindableDirective = ngDirective({
            terminal: true,
            priority: 1000
        });
        var ngOptionsMinErr = minErr('ngOptions');
        var NG_OPTIONS_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?(?:\s+disable\s+when\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/;
        var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
            function parseOptionsExpression(optionsExp, selectElement, scope) {
                var match = optionsExp.match(NG_OPTIONS_REGEXP);
                if (!(match)) {
                    throw ngOptionsMinErr('iexp',
                        "Expected expression in form of " +
                        "'_select_ (as _label_)? for (_key_,)?_value_ in _collection_'" +
                        " but got '{0}'. Element: {1}",
                        optionsExp, startingTag(selectElement));
                }
                var valueName = match[5] || match[7];
                var keyName = match[6];
                var selectAs = / as /.test(match[0]) && match[1];
                var trackBy = match[9];
                var valueFn = $parse(match[2] ? match[1] : valueName);
                var selectAsFn = selectAs && $parse(selectAs);
                var viewValueFn = selectAsFn || valueFn;
                var trackByFn = trackBy && $parse(trackBy);
                var getTrackByValueFn = trackBy ?
                    function(value, locals) {
                        return trackByFn(scope, locals);
                    } :
                    function getHashOfValue(value) {
                        return hashKey(value);
                    };
                var getTrackByValue = function(value, key) {
                    return getTrackByValueFn(value, getLocals(value, key));
                };
                var displayFn = $parse(match[2] || match[1]);
                var groupByFn = $parse(match[3] || '');
                var disableWhenFn = $parse(match[4] || '');
                var valuesFn = $parse(match[8]);
                var locals = {};
                var getLocals = keyName ? function(value, key) {
                    locals[keyName] = key;
                    locals[valueName] = value;
                    return locals;
                } : function(value) {
                    locals[valueName] = value;
                    return locals;
                };
    
                function Option(selectValue, viewValue, label, group, disabled) {
                    this.selectValue = selectValue;
                    this.viewValue = viewValue;
                    this.label = label;
                    this.group = group;
                    this.disabled = disabled;
                }
    
                function getOptionValuesKeys(optionValues) {
                    var optionValuesKeys;
                    if (!keyName && isArrayLike(optionValues)) {
                        optionValuesKeys = optionValues;
                    } else {
                        optionValuesKeys = [];
                        for (var itemKey in optionValues) {
                            if (optionValues.hasOwnProperty(itemKey) && itemKey.charAt(0) !== '$') {
                                optionValuesKeys.push(itemKey);
                            }
                        }
                    }
                    return optionValuesKeys;
                }
                return {
                    trackBy: trackBy,
                    getTrackByValue: getTrackByValue,
                    getWatchables: $parse(valuesFn, function(optionValues) {
                        var watchedArray = [];
                        optionValues = optionValues || [];
                        var optionValuesKeys = getOptionValuesKeys(optionValues);
                        var optionValuesLength = optionValuesKeys.length;
                        for (var index = 0; index < optionValuesLength; index++) {
                            var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index];
                            var value = optionValues[key];
                            var locals = getLocals(value, key);
                            var selectValue = getTrackByValueFn(value, locals);
                            watchedArray.push(selectValue);
                            if (match[2] || match[1]) {
                                var label = displayFn(scope, locals);
                                watchedArray.push(label);
                            }
                            if (match[4]) {
                                var disableWhen = disableWhenFn(scope, locals);
                                watchedArray.push(disableWhen);
                            }
                        }
                        return watchedArray;
                    }),
                    getOptions: function() {
                        var optionItems = [];
                        var selectValueMap = {};
                        var optionValues = valuesFn(scope) || [];
                        var optionValuesKeys = getOptionValuesKeys(optionValues);
                        var optionValuesLength = optionValuesKeys.length;
                        for (var index = 0; index < optionValuesLength; index++) {
                            var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index];
                            var value = optionValues[key];
                            var locals = getLocals(value, key);
                            var viewValue = viewValueFn(scope, locals);
                            var selectValue = getTrackByValueFn(viewValue, locals);
                            var label = displayFn(scope, locals);
                            var group = groupByFn(scope, locals);
                            var disabled = disableWhenFn(scope, locals);
                            var optionItem = new Option(selectValue, viewValue, label, group, disabled);
                            optionItems.push(optionItem);
                            selectValueMap[selectValue] = optionItem;
                        }
                        return {
                            items: optionItems,
                            selectValueMap: selectValueMap,
                            getOptionFromViewValue: function(value) {
                                return selectValueMap[getTrackByValue(value)];
                            },
                            getViewValueFromOption: function(option) {
                                return trackBy ? angular.copy(option.viewValue) : option.viewValue;
                            }
                        };
                    }
                };
            }
            var optionTemplate = document.createElement('option'),
                optGroupTemplate = document.createElement('optgroup');
    
            function ngOptionsPostLink(scope, selectElement, attr, ctrls) {
                var selectCtrl = ctrls[0];
                var ngModelCtrl = ctrls[1];
                var multiple = attr.multiple;
                var emptyOption;
                for (var i = 0, children = selectElement.children(), ii = children.length; i < ii; i++) {
                    if (children[i].value === '') {
                        emptyOption = children.eq(i);
                        break;
                    }
                }
                var providedEmptyOption = !!emptyOption;
                var unknownOption = jqLite(optionTemplate.cloneNode(false));
                unknownOption.val('?');
                var options;
                var ngOptions = parseOptionsExpression(attr.ngOptions, selectElement, scope);
                var renderEmptyOption = function() {
                    if (!providedEmptyOption) {
                        selectElement.prepend(emptyOption);
                    }
                    selectElement.val('');
                    emptyOption.prop('selected', true);
                    emptyOption.attr('selected', true);
                };
                var removeEmptyOption = function() {
                    if (!providedEmptyOption) {
                        emptyOption.remove();
                    }
                };
                var renderUnknownOption = function() {
                    selectElement.prepend(unknownOption);
                    selectElement.val('?');
                    unknownOption.prop('selected', true);
                    unknownOption.attr('selected', true);
                };
                var removeUnknownOption = function() {
                    unknownOption.remove();
                };
                if (!multiple) {
                    selectCtrl.writeValue = function writeNgOptionsValue(value) {
                        var option = options.getOptionFromViewValue(value);
                        if (option && !option.disabled) {
                            if (selectElement[0].value !== option.selectValue) {
                                removeUnknownOption();
                                removeEmptyOption();
                                selectElement[0].value = option.selectValue;
                                option.element.selected = true;
                            }
                            option.element.setAttribute('selected', 'selected');
                        } else {
                            if (value === null || providedEmptyOption) {
                                removeUnknownOption();
                                renderEmptyOption();
                            } else {
                                removeEmptyOption();
                                renderUnknownOption();
                            }
                        }
                    };
                    selectCtrl.readValue = function readNgOptionsValue() {
                        var selectedOption = options.selectValueMap[selectElement.val()];
                        if (selectedOption && !selectedOption.disabled) {
                            removeEmptyOption();
                            removeUnknownOption();
                            return options.getViewValueFromOption(selectedOption);
                        }
                        return null;
                    };
                    if (ngOptions.trackBy) {
                        scope.$watch(
                            function() {
                                return ngOptions.getTrackByValue(ngModelCtrl.$viewValue);
                            },
                            function() {
                                ngModelCtrl.$render();
                            }
                        );
                    }
                } else {
                    ngModelCtrl.$isEmpty = function(value) {
                        return !value || value.length === 0;
                    };
                    selectCtrl.writeValue = function writeNgOptionsMultiple(value) {
                        options.items.forEach(function(option) {
                            option.element.selected = false;
                        });
                        if (value) {
                            value.forEach(function(item) {
                                var option = options.getOptionFromViewValue(item);
                                if (option && !option.disabled) option.element.selected = true;
                            });
                        }
                    };
                    selectCtrl.readValue = function readNgOptionsMultiple() {
                        var selectedValues = selectElement.val() || [],
                            selections = [];
                        forEach(selectedValues, function(value) {
                            var option = options.selectValueMap[value];
                            if (option && !option.disabled) selections.push(options.getViewValueFromOption(option));
                        });
                        return selections;
                    };
                    if (ngOptions.trackBy) {
                        scope.$watchCollection(function() {
                            if (isArray(ngModelCtrl.$viewValue)) {
                                return ngModelCtrl.$viewValue.map(function(value) {
                                    return ngOptions.getTrackByValue(value);
                                });
                            }
                        }, function() {
                            ngModelCtrl.$render();
                        });
                    }
                }
                if (providedEmptyOption) {
                    emptyOption.remove();
                    $compile(emptyOption)(scope);
                    emptyOption.removeClass('ng-scope');
                } else {
                    emptyOption = jqLite(optionTemplate.cloneNode(false));
                }
                updateOptions();
                scope.$watchCollection(ngOptions.getWatchables, updateOptions);
    
                function updateOptionElement(option, element) {
                    option.element = element;
                    element.disabled = option.disabled;
                    if (option.label !== element.label) {
                        element.label = option.label;
                        element.textContent = option.label;
                    }
                    if (option.value !== element.value) element.value = option.selectValue;
                }
    
                function addOrReuseElement(parent, current, type, templateElement) {
                    var element;
                    if (current && lowercase(current.nodeName) === type) {
                        element = current;
                    } else {
                        element = templateElement.cloneNode(false);
                        if (!current) {
                            parent.appendChild(element);
                        } else {
                            parent.insertBefore(element, current);
                        }
                    }
                    return element;
                }
    
                function removeExcessElements(current) {
                    var next;
                    while (current) {
                        next = current.nextSibling;
                        jqLiteRemove(current);
                        current = next;
                    }
                }
    
                function skipEmptyAndUnknownOptions(current) {
                    var emptyOption_ = emptyOption && emptyOption[0];
                    var unknownOption_ = unknownOption && unknownOption[0];
                    if (emptyOption_ || unknownOption_) {
                        while (current &&
                            (current === emptyOption_ ||
                                current === unknownOption_ ||
                                current.nodeType === NODE_TYPE_COMMENT ||
                                (nodeName_(current) === 'option' && current.value === ''))) {
                            current = current.nextSibling;
                        }
                    }
                    return current;
                }
    
                function updateOptions() {
                    var previousValue = options && selectCtrl.readValue();
                    options = ngOptions.getOptions();
                    var groupMap = {};
                    var currentElement = selectElement[0].firstChild;
                    if (providedEmptyOption) {
                        selectElement.prepend(emptyOption);
                    }
                    currentElement = skipEmptyAndUnknownOptions(currentElement);
                    options.items.forEach(function updateOption(option) {
                        var group;
                        var groupElement;
                        var optionElement;
                        if (isDefined(option.group)) {
                            group = groupMap[option.group];
                            if (!group) {
                                groupElement = addOrReuseElement(selectElement[0],
                                    currentElement,
                                    'optgroup',
                                    optGroupTemplate);
                                currentElement = groupElement.nextSibling;
                                groupElement.label = option.group;
                                group = groupMap[option.group] = {
                                    groupElement: groupElement,
                                    currentOptionElement: groupElement.firstChild
                                };
                            }
                            optionElement = addOrReuseElement(group.groupElement,
                                group.currentOptionElement,
                                'option',
                                optionTemplate);
                            updateOptionElement(option, optionElement);
                            group.currentOptionElement = optionElement.nextSibling;
                        } else {
                            optionElement = addOrReuseElement(selectElement[0],
                                currentElement,
                                'option',
                                optionTemplate);
                            updateOptionElement(option, optionElement);
                            currentElement = optionElement.nextSibling;
                        }
                    });
                    Object.keys(groupMap).forEach(function(key) {
                        removeExcessElements(groupMap[key].currentOptionElement);
                    });
                    removeExcessElements(currentElement);
                    ngModelCtrl.$render();
                    if (!ngModelCtrl.$isEmpty(previousValue)) {
                        var nextValue = selectCtrl.readValue();
                        var isNotPrimitive = ngOptions.trackBy || multiple;
                        if (isNotPrimitive ? !equals(previousValue, nextValue) : previousValue !== nextValue) {
                            ngModelCtrl.$setViewValue(nextValue);
                            ngModelCtrl.$render();
                        }
                    }
                }
            }
            return {
                restrict: 'A',
                terminal: true,
                require: ['select', 'ngModel'],
                link: {
                    pre: function ngOptionsPreLink(scope, selectElement, attr, ctrls) {
                        ctrls[0].registerOption = noop;
                    },
                    post: ngOptionsPostLink
                }
            };
        }];
        var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale, $interpolate, $log) {
            var BRACE = /{}/g,
                IS_WHEN = /^when(Minus)?(.+)$/;
            return {
                link: function(scope, element, attr) {
                    var numberExp = attr.count,
                        whenExp = attr.$attr.when && element.attr(attr.$attr.when),
                        offset = attr.offset || 0,
                        whens = scope.$eval(whenExp) || {},
                        whensExpFns = {},
                        startSymbol = $interpolate.startSymbol(),
                        endSymbol = $interpolate.endSymbol(),
                        braceReplacement = startSymbol + numberExp + '-' + offset + endSymbol,
                        watchRemover = angular.noop,
                        lastCount;
                    forEach(attr, function(expression, attributeName) {
                        var tmpMatch = IS_WHEN.exec(attributeName);
                        if (tmpMatch) {
                            var whenKey = (tmpMatch[1] ? '-' : '') + lowercase(tmpMatch[2]);
                            whens[whenKey] = element.attr(attr.$attr[attributeName]);
                        }
                    });
                    forEach(whens, function(expression, key) {
                        whensExpFns[key] = $interpolate(expression.replace(BRACE, braceReplacement));
                    });
                    scope.$watch(numberExp, function ngPluralizeWatchAction(newVal) {
                        var count = parseFloat(newVal);
                        var countIsNaN = isNaN(count);
                        if (!countIsNaN && !(count in whens)) {
                            count = $locale.pluralCat(count - offset);
                        }
                        if ((count !== lastCount) && !(countIsNaN && isNumber(lastCount) && isNaN(lastCount))) {
                            watchRemover();
                            var whenExpFn = whensExpFns[count];
                            if (isUndefined(whenExpFn)) {
                                if (newVal != null) {
                                    $log.debug("ngPluralize: no rule defined for '" + count + "' in " + whenExp);
                                }
                                watchRemover = noop;
                                updateElementText();
                            } else {
                                watchRemover = scope.$watch(whenExpFn, updateElementText);
                            }
                            lastCount = count;
                        }
                    });
    
                    function updateElementText(newText) {
                        element.text(newText || '');
                    }
                }
            };
        }];
        var ngRepeatDirective = ['$parse', '$animate', '$compile', function($parse, $animate, $compile) {
            var NG_REMOVED = '$$NG_REMOVED';
            var ngRepeatMinErr = minErr('ngRepeat');
            var updateScope = function(scope, index, valueIdentifier, value, keyIdentifier, key, arrayLength) {
                scope[valueIdentifier] = value;
                if (keyIdentifier) scope[keyIdentifier] = key;
                scope.$index = index;
                scope.$first = (index === 0);
                scope.$last = (index === (arrayLength - 1));
                scope.$middle = !(scope.$first || scope.$last);
                scope.$odd = !(scope.$even = (index & 1) === 0);
            };
            var getBlockStart = function(block) {
                return block.clone[0];
            };
            var getBlockEnd = function(block) {
                return block.clone[block.clone.length - 1];
            };
            return {
                restrict: 'A',
                multiElement: true,
                transclude: 'element',
                priority: 1000,
                terminal: true,
                $$tlb: true,
                compile: function ngRepeatCompile($element, $attr) {
                    var expression = $attr.ngRepeat;
                    var ngRepeatEndComment = $compile.$$createComment('end ngRepeat', expression);
                    var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
                    if (!match) {
                        throw ngRepeatMinErr('iexp', "Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'.",
                            expression);
                    }
                    var lhs = match[1];
                    var rhs = match[2];
                    var aliasAs = match[3];
                    var trackByExp = match[4];
                    match = lhs.match(/^(?:(\s*[\$\w]+)|\(\s*([\$\w]+)\s*,\s*([\$\w]+)\s*\))$/);
                    if (!match) {
                        throw ngRepeatMinErr('iidexp', "'_item_' in '_item_ in _collection_' should be an identifier or '(_key_, _value_)' expression, but got '{0}'.",
                            lhs);
                    }
                    var valueIdentifier = match[3] || match[1];
                    var keyIdentifier = match[2];
                    if (aliasAs && (!/^[$a-zA-Z_][$a-zA-Z0-9_]*$/.test(aliasAs) ||
                            /^(null|undefined|this|\$index|\$first|\$middle|\$last|\$even|\$odd|\$parent|\$root|\$id)$/.test(aliasAs))) {
                        throw ngRepeatMinErr('badident', "alias '{0}' is invalid --- must be a valid JS identifier which is not a reserved name.",
                            aliasAs);
                    }
                    var trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn;
                    var hashFnLocals = {
                        $id: hashKey
                    };
                    if (trackByExp) {
                        trackByExpGetter = $parse(trackByExp);
                    } else {
                        trackByIdArrayFn = function(key, value) {
                            return hashKey(value);
                        };
                        trackByIdObjFn = function(key) {
                            return key;
                        };
                    }
                    return function ngRepeatLink($scope, $element, $attr, ctrl, $transclude) {
                        if (trackByExpGetter) {
                            trackByIdExpFn = function(key, value, index) {
                                if (keyIdentifier) hashFnLocals[keyIdentifier] = key;
                                hashFnLocals[valueIdentifier] = value;
                                hashFnLocals.$index = index;
                                return trackByExpGetter($scope, hashFnLocals);
                            };
                        }
                        var lastBlockMap = createMap();
                        $scope.$watchCollection(rhs, function ngRepeatAction(collection) {
                            var index, length,
                                previousNode = $element[0],
                                nextNode,
                                nextBlockMap = createMap(),
                                collectionLength,
                                key, value,
                                trackById,
                                trackByIdFn,
                                collectionKeys,
                                block,
                                nextBlockOrder,
                                elementsToRemove;
                            if (aliasAs) {
                                $scope[aliasAs] = collection;
                            }
                            if (isArrayLike(collection)) {
                                collectionKeys = collection;
                                trackByIdFn = trackByIdExpFn || trackByIdArrayFn;
                            } else {
                                trackByIdFn = trackByIdExpFn || trackByIdObjFn;
                                collectionKeys = [];
                                for (var itemKey in collection) {
                                    if (hasOwnProperty.call(collection, itemKey) && itemKey.charAt(0) !== '$') {
                                        collectionKeys.push(itemKey);
                                    }
                                }
                            }
                            collectionLength = collectionKeys.length;
                            nextBlockOrder = new Array(collectionLength);
                            for (index = 0; index < collectionLength; index++) {
                                key = (collection === collectionKeys) ? index : collectionKeys[index];
                                value = collection[key];
                                trackById = trackByIdFn(key, value, index);
                                if (lastBlockMap[trackById]) {
                                    block = lastBlockMap[trackById];
                                    delete lastBlockMap[trackById];
                                    nextBlockMap[trackById] = block;
                                    nextBlockOrder[index] = block;
                                } else if (nextBlockMap[trackById]) {
                                    forEach(nextBlockOrder, function(block) {
                                        if (block && block.scope) lastBlockMap[block.id] = block;
                                    });
                                    throw ngRepeatMinErr('dupes',
                                        "Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}, Duplicate value: {2}",
                                        expression, trackById, value);
                                } else {
                                    nextBlockOrder[index] = {
                                        id: trackById,
                                        scope: undefined,
                                        clone: undefined
                                    };
                                    nextBlockMap[trackById] = true;
                                }
                            }
                            for (var blockKey in lastBlockMap) {
                                block = lastBlockMap[blockKey];
                                elementsToRemove = getBlockNodes(block.clone);
                                $animate.leave(elementsToRemove);
                                if (elementsToRemove[0].parentNode) {
                                    for (index = 0, length = elementsToRemove.length; index < length; index++) {
                                        elementsToRemove[index][NG_REMOVED] = true;
                                    }
                                }
                                block.scope.$destroy();
                            }
                            for (index = 0; index < collectionLength; index++) {
                                key = (collection === collectionKeys) ? index : collectionKeys[index];
                                value = collection[key];
                                block = nextBlockOrder[index];
                                if (block.scope) {
                                    nextNode = previousNode;
                                    do {
                                        nextNode = nextNode.nextSibling;
                                    } while (nextNode && nextNode[NG_REMOVED]);
                                    if (getBlockStart(block) != nextNode) {
                                        $animate.move(getBlockNodes(block.clone), null, previousNode);
                                    }
                                    previousNode = getBlockEnd(block);
                                    updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength);
                                } else {
                                    $transclude(function ngRepeatTransclude(clone, scope) {
                                        block.scope = scope;
                                        var endNode = ngRepeatEndComment.cloneNode(false);
                                        clone[clone.length++] = endNode;
                                        $animate.enter(clone, null, previousNode);
                                        previousNode = endNode;
                                        block.clone = clone;
                                        nextBlockMap[block.id] = block;
                                        updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength);
                                    });
                                }
                            }
                            lastBlockMap = nextBlockMap;
                        });
                    };
                }
            };
        }];
        var NG_HIDE_CLASS = 'ng-hide';
        var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';
        var ngShowDirective = ['$animate', function($animate) {
            return {
                restrict: 'A',
                multiElement: true,
                link: function(scope, element, attr) {
                    scope.$watch(attr.ngShow, function ngShowWatchAction(value) {
                        $animate[value ? 'removeClass' : 'addClass'](element, NG_HIDE_CLASS, {
                            tempClasses: NG_HIDE_IN_PROGRESS_CLASS
                        });
                    });
                }
            };
        }];
        var ngHideDirective = ['$animate', function($animate) {
            return {
                restrict: 'A',
                multiElement: true,
                link: function(scope, element, attr) {
                    scope.$watch(attr.ngHide, function ngHideWatchAction(value) {
                        $animate[value ? 'addClass' : 'removeClass'](element, NG_HIDE_CLASS, {
                            tempClasses: NG_HIDE_IN_PROGRESS_CLASS
                        });
                    });
                }
            };
        }];
        var ngStyleDirective = ngDirective(function(scope, element, attr) {
            scope.$watch(attr.ngStyle, function ngStyleWatchAction(newStyles, oldStyles) {
                if (oldStyles && (newStyles !== oldStyles)) {
                    forEach(oldStyles, function(val, style) {
                        element.css(style, '');
                    });
                }
                if (newStyles) element.css(newStyles);
            }, true);
        });
        var ngSwitchDirective = ['$animate', '$compile', function($animate, $compile) {
            return {
                require: 'ngSwitch',
                controller: ['$scope', function ngSwitchController() {
                    this.cases = {};
                }],
                link: function(scope, element, attr, ngSwitchController) {
                    var watchExpr = attr.ngSwitch || attr.on,
                        selectedTranscludes = [],
                        selectedElements = [],
                        previousLeaveAnimations = [],
                        selectedScopes = [];
                    var spliceFactory = function(array, index) {
                        return function() {
                            array.splice(index, 1);
                        };
                    };
                    scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
                        var i, ii;
                        for (i = 0, ii = previousLeaveAnimations.length; i < ii; ++i) {
                            $animate.cancel(previousLeaveAnimations[i]);
                        }
                        previousLeaveAnimations.length = 0;
                        for (i = 0, ii = selectedScopes.length; i < ii; ++i) {
                            var selected = getBlockNodes(selectedElements[i].clone);
                            selectedScopes[i].$destroy();
                            var promise = previousLeaveAnimations[i] = $animate.leave(selected);
                            promise.then(spliceFactory(previousLeaveAnimations, i));
                        }
                        selectedElements.length = 0;
                        selectedScopes.length = 0;
                        if ((selectedTranscludes = ngSwitchController.cases['!' + value] || ngSwitchController.cases['?'])) {
                            forEach(selectedTranscludes, function(selectedTransclude) {
                                selectedTransclude.transclude(function(caseElement, selectedScope) {
                                    selectedScopes.push(selectedScope);
                                    var anchor = selectedTransclude.element;
                                    caseElement[caseElement.length++] = $compile.$$createComment('end ngSwitchWhen');
                                    var block = {
                                        clone: caseElement
                                    };
                                    selectedElements.push(block);
                                    $animate.enter(caseElement, anchor.parent(), anchor);
                                });
                            });
                        }
                    });
                }
            };
        }];
        var ngSwitchWhenDirective = ngDirective({
            transclude: 'element',
            priority: 1200,
            require: '^ngSwitch',
            multiElement: true,
            link: function(scope, element, attrs, ctrl, $transclude) {
                ctrl.cases['!' + attrs.ngSwitchWhen] = (ctrl.cases['!' + attrs.ngSwitchWhen] || []);
                ctrl.cases['!' + attrs.ngSwitchWhen].push({
                    transclude: $transclude,
                    element: element
                });
            }
        });
        var ngSwitchDefaultDirective = ngDirective({
            transclude: 'element',
            priority: 1200,
            require: '^ngSwitch',
            multiElement: true,
            link: function(scope, element, attr, ctrl, $transclude) {
                ctrl.cases['?'] = (ctrl.cases['?'] || []);
                ctrl.cases['?'].push({
                    transclude: $transclude,
                    element: element
                });
            }
        });
        var ngTranscludeMinErr = minErr('ngTransclude');
        var ngTranscludeDirective = ngDirective({
            restrict: 'EAC',
            link: function($scope, $element, $attrs, controller, $transclude) {
                if ($attrs.ngTransclude === $attrs.$attr.ngTransclude) {
                    $attrs.ngTransclude = '';
                }
    
                function ngTranscludeCloneAttachFn(clone) {
                    if (clone.length) {
                        $element.empty();
                        $element.append(clone);
                    }
                }
                if (!$transclude) {
                    throw ngTranscludeMinErr('orphan',
                        'Illegal use of ngTransclude directive in the template! ' +
                        'No parent directive that requires a transclusion found. ' +
                        'Element: {0}',
                        startingTag($element));
                }
                var slotName = $attrs.ngTransclude || $attrs.ngTranscludeSlot;
                $transclude(ngTranscludeCloneAttachFn, null, slotName);
            }
        });
        var scriptDirective = ['$templateCache', function($templateCache) {
            return {
                restrict: 'E',
                terminal: true,
                compile: function(element, attr) {
                    if (attr.type == 'text/ng-template') {
                        var templateUrl = attr.id,
                            text = element[0].text;
                        $templateCache.put(templateUrl, text);
                    }
                }
            };
        }];
        var noopNgModelController = {
            $setViewValue: noop,
            $render: noop
        };
    
        function chromeHack(optionElement) {
            if (optionElement[0].hasAttribute('selected')) {
                optionElement[0].selected = true;
            }
        }
        var SelectController = ['$element', '$scope', function($element, $scope) {
            var self = this,
                optionsMap = new HashMap();
            self.ngModelCtrl = noopNgModelController;
            self.unknownOption = jqLite(document.createElement('option'));
            self.renderUnknownOption = function(val) {
                var unknownVal = '? ' + hashKey(val) + ' ?';
                self.unknownOption.val(unknownVal);
                $element.prepend(self.unknownOption);
                $element.val(unknownVal);
            };
            $scope.$on('$destroy', function() {
                self.renderUnknownOption = noop;
            });
            self.removeUnknownOption = function() {
                if (self.unknownOption.parent()) self.unknownOption.remove();
            };
            self.readValue = function readSingleValue() {
                self.removeUnknownOption();
                return $element.val();
            };
            self.writeValue = function writeSingleValue(value) {
                if (self.hasOption(value)) {
                    self.removeUnknownOption();
                    $element.val(value);
                    if (value === '') self.emptyOption.prop('selected', true);
                } else {
                    if (value == null && self.emptyOption) {
                        self.removeUnknownOption();
                        $element.val('');
                    } else {
                        self.renderUnknownOption(value);
                    }
                }
            };
            self.addOption = function(value, element) {
                if (element[0].nodeType === NODE_TYPE_COMMENT) return;
                assertNotHasOwnProperty(value, '"option value"');
                if (value === '') {
                    self.emptyOption = element;
                }
                var count = optionsMap.get(value) || 0;
                optionsMap.put(value, count + 1);
                self.ngModelCtrl.$render();
                chromeHack(element);
            };
            self.removeOption = function(value) {
                var count = optionsMap.get(value);
                if (count) {
                    if (count === 1) {
                        optionsMap.remove(value);
                        if (value === '') {
                            self.emptyOption = undefined;
                        }
                    } else {
                        optionsMap.put(value, count - 1);
                    }
                }
            };
            self.hasOption = function(value) {
                return !!optionsMap.get(value);
            };
            self.registerOption = function(optionScope, optionElement, optionAttrs, interpolateValueFn, interpolateTextFn) {
                if (interpolateValueFn) {
                    var oldVal;
                    optionAttrs.$observe('value', function valueAttributeObserveAction(newVal) {
                        if (isDefined(oldVal)) {
                            self.removeOption(oldVal);
                        }
                        oldVal = newVal;
                        self.addOption(newVal, optionElement);
                    });
                } else if (interpolateTextFn) {
                    optionScope.$watch(interpolateTextFn, function interpolateWatchAction(newVal, oldVal) {
                        optionAttrs.$set('value', newVal);
                        if (oldVal !== newVal) {
                            self.removeOption(oldVal);
                        }
                        self.addOption(newVal, optionElement);
                    });
                } else {
                    self.addOption(optionAttrs.value, optionElement);
                }
                optionElement.on('$destroy', function() {
                    self.removeOption(optionAttrs.value);
                    self.ngModelCtrl.$render();
                });
            };
        }];
        var selectDirective = function() {
            return {
                restrict: 'E',
                require: ['select', '?ngModel'],
                controller: SelectController,
                priority: 1,
                link: {
                    pre: selectPreLink,
                    post: selectPostLink
                }
            };
    
            function selectPreLink(scope, element, attr, ctrls) {
                var ngModelCtrl = ctrls[1];
                if (!ngModelCtrl) return;
                var selectCtrl = ctrls[0];
                selectCtrl.ngModelCtrl = ngModelCtrl;
                element.on('change', function() {
                    scope.$apply(function() {
                        ngModelCtrl.$setViewValue(selectCtrl.readValue());
                    });
                });
                if (attr.multiple) {
                    selectCtrl.readValue = function readMultipleValue() {
                        var array = [];
                        forEach(element.find('option'), function(option) {
                            if (option.selected) {
                                array.push(option.value);
                            }
                        });
                        return array;
                    };
                    selectCtrl.writeValue = function writeMultipleValue(value) {
                        var items = new HashMap(value);
                        forEach(element.find('option'), function(option) {
                            option.selected = isDefined(items.get(option.value));
                        });
                    };
                    var lastView, lastViewRef = NaN;
                    scope.$watch(function selectMultipleWatch() {
                        if (lastViewRef === ngModelCtrl.$viewValue && !equals(lastView, ngModelCtrl.$viewValue)) {
                            lastView = shallowCopy(ngModelCtrl.$viewValue);
                            ngModelCtrl.$render();
                        }
                        lastViewRef = ngModelCtrl.$viewValue;
                    });
                    ngModelCtrl.$isEmpty = function(value) {
                        return !value || value.length === 0;
                    };
                }
            }
    
            function selectPostLink(scope, element, attrs, ctrls) {
                var ngModelCtrl = ctrls[1];
                if (!ngModelCtrl) return;
                var selectCtrl = ctrls[0];
                ngModelCtrl.$render = function() {
                    selectCtrl.writeValue(ngModelCtrl.$viewValue);
                };
            }
        };
        var optionDirective = ['$interpolate', function($interpolate) {
            return {
                restrict: 'E',
                priority: 100,
                compile: function(element, attr) {
                    if (isDefined(attr.value)) {
                        var interpolateValueFn = $interpolate(attr.value, true);
                    } else {
                        var interpolateTextFn = $interpolate(element.text(), true);
                        if (!interpolateTextFn) {
                            attr.$set('value', element.text());
                        }
                    }
                    return function(scope, element, attr) {
                        var selectCtrlName = '$selectController',
                            parent = element.parent(),
                            selectCtrl = parent.data(selectCtrlName) ||
                            parent.parent().data(selectCtrlName);
                        if (selectCtrl) {
                            selectCtrl.registerOption(scope, element, attr, interpolateValueFn, interpolateTextFn);
                        }
                    };
                }
            };
        }];
        var styleDirective = valueFn({
            restrict: 'E',
            terminal: false
        });
        var requiredDirective = function() {
            return {
                restrict: 'A',
                require: '?ngModel',
                link: function(scope, elm, attr, ctrl) {
                    if (!ctrl) return;
                    attr.required = true;
                    ctrl.$validators.required = function(modelValue, viewValue) {
                        return !attr.required || !ctrl.$isEmpty(viewValue);
                    };
                    attr.$observe('required', function() {
                        ctrl.$validate();
                    });
                }
            };
        };
        var patternDirective = function() {
            return {
                restrict: 'A',
                require: '?ngModel',
                link: function(scope, elm, attr, ctrl) {
                    if (!ctrl) return;
                    var regexp, patternExp = attr.ngPattern || attr.pattern;
                    attr.$observe('pattern', function(regex) {
                        if (isString(regex) && regex.length > 0) {
                            regex = new RegExp('^' + regex + '$');
                        }
                        if (regex && !regex.test) {
                            throw minErr('ngPattern')('noregexp',
                                'Expected {0} to be a RegExp but was {1}. Element: {2}', patternExp,
                                regex, startingTag(elm));
                        }
                        regexp = regex || undefined;
                        ctrl.$validate();
                    });
                    ctrl.$validators.pattern = function(modelValue, viewValue) {
                        return ctrl.$isEmpty(viewValue) || isUndefined(regexp) || regexp.test(viewValue);
                    };
                }
            };
        };
        var maxlengthDirective = function() {
            return {
                restrict: 'A',
                require: '?ngModel',
                link: function(scope, elm, attr, ctrl) {
                    if (!ctrl) return;
                    var maxlength = -1;
                    attr.$observe('maxlength', function(value) {
                        var intVal = toInt(value);
                        maxlength = isNaN(intVal) ? -1 : intVal;
                        ctrl.$validate();
                    });
                    ctrl.$validators.maxlength = function(modelValue, viewValue) {
                        return (maxlength < 0) || ctrl.$isEmpty(viewValue) || (viewValue.length <= maxlength);
                    };
                }
            };
        };
        var minlengthDirective = function() {
            return {
                restrict: 'A',
                require: '?ngModel',
                link: function(scope, elm, attr, ctrl) {
                    if (!ctrl) return;
                    var minlength = 0;
                    attr.$observe('minlength', function(value) {
                        minlength = toInt(value) || 0;
                        ctrl.$validate();
                    });
                    ctrl.$validators.minlength = function(modelValue, viewValue) {
                        return ctrl.$isEmpty(viewValue) || viewValue.length >= minlength;
                    };
                }
            };
        };
        if (window.angular.bootstrap) {
            if (window.console) {
                console.log('WARNING: Tried to load angular more than once.');
            }
            return;
        }
        bindJQuery();
        publishExternalAPI(angular);
        angular.module("ngLocale", [], ["$provide", function($provide) {
            var PLURAL_CATEGORY = {
                ZERO: "zero",
                ONE: "one",
                TWO: "two",
                FEW: "few",
                MANY: "many",
                OTHER: "other"
            };
    
            function getDecimals(n) {
                n = n + '';
                var i = n.indexOf('.');
                return (i == -1) ? 0 : n.length - i - 1;
            }
    
            function getVF(n, opt_precision) {
                var v = opt_precision;
                if (undefined === v) {
                    v = Math.min(getDecimals(n), 3);
                }
                var base = Math.pow(10, v);
                var f = ((n * base) | 0) % base;
                return {
                    v: v,
                    f: f
                };
            }
            $provide.value("$locale", {
                "DATETIME_FORMATS": {
                    "AMPMS": [
                        "AM",
                        "PM"
                    ],
                    "DAY": [
                        "Sunday",
                        "Monday",
                        "Tuesday",
                        "Wednesday",
                        "Thursday",
                        "Friday",
                        "Saturday"
                    ],
                    "ERANAMES": [
                        "Before Christ",
                        "Anno Domini"
                    ],
                    "ERAS": [
                        "BC",
                        "AD"
                    ],
                    "FIRSTDAYOFWEEK": 6,
                    "MONTH": [
                        "January",
                        "February",
                        "March",
                        "April",
                        "May",
                        "June",
                        "July",
                        "August",
                        "September",
                        "October",
                        "November",
                        "December"
                    ],
                    "SHORTDAY": [
                        "Sun",
                        "Mon",
                        "Tue",
                        "Wed",
                        "Thu",
                        "Fri",
                        "Sat"
                    ],
                    "SHORTMONTH": [
                        "Jan",
                        "Feb",
                        "Mar",
                        "Apr",
                        "May",
                        "Jun",
                        "Jul",
                        "Aug",
                        "Sep",
                        "Oct",
                        "Nov",
                        "Dec"
                    ],
                    "STANDALONEMONTH": [
                        "January",
                        "February",
                        "March",
                        "April",
                        "May",
                        "June",
                        "July",
                        "August",
                        "September",
                        "October",
                        "November",
                        "December"
                    ],
                    "WEEKENDRANGE": [
                        5,
                        6
                    ],
                    "fullDate": "EEEE, MMMM d, y",
                    "longDate": "MMMM d, y",
                    "medium": "MMM d, y h:mm:ss a",
                    "mediumDate": "MMM d, y",
                    "mediumTime": "h:mm:ss a",
                    "short": "M/d/yy h:mm a",
                    "shortDate": "M/d/yy",
                    "shortTime": "h:mm a"
                },
                "NUMBER_FORMATS": {
                    "CURRENCY_SYM": "$",
                    "DECIMAL_SEP": ".",
                    "GROUP_SEP": ",",
                    "PATTERNS": [{
                            "gSize": 3,
                            "lgSize": 3,
                            "maxFrac": 3,
                            "minFrac": 0,
                            "minInt": 1,
                            "negPre": "-",
                            "negSuf": "",
                            "posPre": "",
                            "posSuf": ""
                        },
                        {
                            "gSize": 3,
                            "lgSize": 3,
                            "maxFrac": 2,
                            "minFrac": 2,
                            "minInt": 1,
                            "negPre": "-\u00a4",
                            "negSuf": "",
                            "posPre": "\u00a4",
                            "posSuf": ""
                        }
                    ]
                },
                "id": "en-us",
                "localeID": "en_US",
                "pluralCat": function(n, opt_precision) {
                    var i = n | 0;
                    var vf = getVF(n, opt_precision);
                    if (i == 1 && vf.v == 0) {
                        return PLURAL_CATEGORY.ONE;
                    }
                    return PLURAL_CATEGORY.OTHER;
                }
            });
        }]);
        jqLite(document).ready(function() {
            angularInit(document, bootstrap);
        });
    })(window, document);
    !window.angular.$$csp().noInlineStyle && window.angular.element(document.head).prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\\:form{display:block;}.ng-animate-shim{visibility:hidden;}.ng-anchor{position:absolute;}</style>');;
    /*! RESOURCE: /scripts/angular_1.5.3/angular-sanitize.js */
    (function(window, angular, undefined) {
        'use strict';
        var $sanitizeMinErr = angular.$$minErr('$sanitize');
    
        function $SanitizeProvider() {
            var svgEnabled = false;
            this.$get = ['$$sanitizeUri', function($$sanitizeUri) {
                if (svgEnabled) {
                    angular.extend(validElements, svgElements);
                }
                return function(html) {
                    var buf = [];
                    htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) {
                        return !/^unsafe:/.test($$sanitizeUri(uri, isImage));
                    }));
                    return buf.join('');
                };
            }];
            this.enableSvg = function(enableSvg) {
                if (angular.isDefined(enableSvg)) {
                    svgEnabled = enableSvg;
                    return this;
                } else {
                    return svgEnabled;
                }
            };
        }
    
        function sanitizeText(chars) {
            var buf = [];
            var writer = htmlSanitizeWriter(buf, angular.noop);
            writer.chars(chars);
            return buf.join('');
        }
        var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
            NON_ALPHANUMERIC_REGEXP = /([^\#-~ |!])/g;
        var voidElements = toMap("area,br,col,hr,img,wbr");
        var optionalEndTagBlockElements = toMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),
            optionalEndTagInlineElements = toMap("rp,rt"),
            optionalEndTagElements = angular.extend({},
                optionalEndTagInlineElements,
                optionalEndTagBlockElements);
        var blockElements = angular.extend({}, optionalEndTagBlockElements, toMap("address,article," +
            "aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," +
            "h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,section,table,ul"));
        var inlineElements = angular.extend({}, optionalEndTagInlineElements, toMap("a,abbr,acronym,b," +
            "bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," +
            "samp,small,span,strike,strong,sub,sup,time,tt,u,var"));
        var svgElements = toMap("circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph," +
            "hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline," +
            "radialGradient,rect,stop,svg,switch,text,title,tspan");
        var blockedElements = toMap("script,style");
        var validElements = angular.extend({},
            voidElements,
            blockElements,
            inlineElements,
            optionalEndTagElements);
        var uriAttrs = toMap("background,cite,href,longdesc,src,xlink:href");
        var htmlAttrs = toMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' +
            'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,' +
            'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,' +
            'scope,scrolling,shape,size,span,start,summary,tabindex,target,title,type,' +
            'valign,value,vspace,width');
        var svgAttrs = toMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' +
            'baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,' +
            'cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,' +
            'font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,' +
            'height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,keySplines,keyTimes,lang,' +
            'marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mathematical,' +
            'max,min,offset,opacity,orient,origin,overline-position,overline-thickness,panose-1,' +
            'path,pathLength,points,preserveAspectRatio,r,refX,refY,repeatCount,repeatDur,' +
            'requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,stemv,stop-color,' +
            'stop-opacity,strikethrough-position,strikethrough-thickness,stroke,stroke-dasharray,' +
            'stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,' +
            'stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,underline-position,' +
            'underline-thickness,unicode,unicode-range,units-per-em,values,version,viewBox,visibility,' +
            'width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,xlink:show,xlink:title,' +
            'xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,zoomAndPan', true);
        var validAttrs = angular.extend({},
            uriAttrs,
            svgAttrs,
            htmlAttrs);
    
        function toMap(str, lowercaseKeys) {
            var obj = {},
                items = str.split(','),
                i;
            for (i = 0; i < items.length; i++) {
                obj[lowercaseKeys ? angular.lowercase(items[i]) : items[i]] = true;
            }
            return obj;
        }
        var inertBodyElement;
        (function(window) {
            var doc;
            if (window.document && window.document.implementation) {
                doc = window.document.implementation.createHTMLDocument("inert");
            } else {
                throw $sanitizeMinErr('noinert', "Can't create an inert html document");
            }
            var docElement = doc.documentElement || doc.getDocumentElement();
            var bodyElements = docElement.getElementsByTagName('body');
            if (bodyElements.length === 1) {
                inertBodyElement = bodyElements[0];
            } else {
                var html = doc.createElement('html');
                inertBodyElement = doc.createElement('body');
                html.appendChild(inertBodyElement);
                doc.appendChild(html);
            }
        })(window);
    
        function htmlParser(html, handler) {
            if (html === null || html === undefined) {
                html = '';
            } else if (typeof html !== 'string') {
                html = '' + html;
            }
            inertBodyElement.innerHTML = html;
            var mXSSAttempts = 5;
            do {
                if (mXSSAttempts === 0) {
                    throw $sanitizeMinErr('uinput', "Failed to sanitize html because the input is unstable");
                }
                mXSSAttempts--;
                if (document.documentMode <= 11) {
                    stripCustomNsAttrs(inertBodyElement);
                }
                html = inertBodyElement.innerHTML;
                inertBodyElement.innerHTML = html;
            } while (html !== inertBodyElement.innerHTML);
            var node = inertBodyElement.firstChild;
            while (node) {
                switch (node.nodeType) {
                    case 1:
                        handler.start(node.nodeName.toLowerCase(), attrToMap(node.attributes));
                        break;
                    case 3:
                        handler.chars(node.textContent);
                        break;
                }
                var nextNode;
                if (!(nextNode = node.firstChild)) {
                    if (node.nodeType == 1) {
                        handler.end(node.nodeName.toLowerCase());
                    }
                    nextNode = node.nextSibling;
                    if (!nextNode) {
                        while (nextNode == null) {
                            node = node.parentNode;
                            if (node === inertBodyElement) break;
                            nextNode = node.nextSibling;
                            if (node.nodeType == 1) {
                                handler.end(node.nodeName.toLowerCase());
                            }
                        }
                    }
                }
                node = nextNode;
            }
            while (node = inertBodyElement.firstChild) {
                inertBodyElement.removeChild(node);
            }
        }
    
        function attrToMap(attrs) {
            var map = {};
            for (var i = 0, ii = attrs.length; i < ii; i++) {
                var attr = attrs[i];
                map[attr.name] = attr.value;
            }
            return map;
        }
    
        function encodeEntities(value) {
            return value.
            replace(/&/g, '&amp;').
            replace(SURROGATE_PAIR_REGEXP, function(value) {
                var hi = value.charCodeAt(0);
                var low = value.charCodeAt(1);
                return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
            }).
            replace(NON_ALPHANUMERIC_REGEXP, function(value) {
                return '&#' + value.charCodeAt(0) + ';';
            }).
            replace(/</g, '&lt;').
            replace(/>/g, '&gt;');
        }
    
        function htmlSanitizeWriter(buf, uriValidator) {
            var ignoreCurrentElement = false;
            var out = angular.bind(buf, buf.push);
            return {
                start: function(tag, attrs) {
                    tag = angular.lowercase(tag);
                    if (!ignoreCurrentElement && blockedElements[tag]) {
                        ignoreCurrentElement = tag;
                    }
                    if (!ignoreCurrentElement && validElements[tag] === true) {
                        out('<');
                        out(tag);
                        angular.forEach(attrs, function(value, key) {
                            var lkey = angular.lowercase(key);
                            var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background');
                            if (validAttrs[lkey] === true &&
                                (uriAttrs[lkey] !== true || uriValidator(value, isImage))) {
                                out(' ');
                                out(key);
                                out('="');
                                out(encodeEntities(value));
                                out('"');
                            }
                        });
                        out('>');
                    }
                },
                end: function(tag) {
                    tag = angular.lowercase(tag);
                    if (!ignoreCurrentElement && validElements[tag] === true && voidElements[tag] !== true) {
                        out('</');
                        out(tag);
                        out('>');
                    }
                    if (tag == ignoreCurrentElement) {
                        ignoreCurrentElement = false;
                    }
                },
                chars: function(chars) {
                    if (!ignoreCurrentElement) {
                        out(encodeEntities(chars));
                    }
                }
            };
        }
    
        function stripCustomNsAttrs(node) {
            if (node.nodeType === Node.ELEMENT_NODE) {
                var attrs = node.attributes;
                for (var i = 0, l = attrs.length; i < l; i++) {
                    var attrNode = attrs[i];
                    var attrName = attrNode.name.toLowerCase();
                    if (attrName === 'xmlns:ns1' || attrName.indexOf('ns1:') === 0) {
                        node.removeAttributeNode(attrNode);
                        i--;
                        l--;
                    }
                }
            }
            var nextNode = node.firstChild;
            if (nextNode) {
                stripCustomNsAttrs(nextNode);
            }
            nextNode = node.nextSibling;
            if (nextNode) {
                stripCustomNsAttrs(nextNode);
            }
        }
        angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider);
        angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
            var LINKY_URL_REGEXP =
                /((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i,
                MAILTO_REGEXP = /^mailto:/i;
            var linkyMinErr = angular.$$minErr('linky');
            var isString = angular.isString;
            return function(text, target, attributes) {
                if (text == null || text === '') return text;
                if (!isString(text)) throw linkyMinErr('notstring', 'Expected string but received: {0}', text);
                var match;
                var raw = text;
                var html = [];
                var url;
                var i;
                while ((match = raw.match(LINKY_URL_REGEXP))) {
                    url = match[0];
                    if (!match[2] && !match[4]) {
                        url = (match[3] ? 'http://' : 'mailto:') + url;
                    }
                    i = match.index;
                    addText(raw.substr(0, i));
                    addLink(url, match[0].replace(MAILTO_REGEXP, ''));
                    raw = raw.substring(i + match[0].length);
                }
                addText(raw);
                return $sanitize(html.join(''));
    
                function addText(text) {
                    if (!text) {
                        return;
                    }
                    html.push(sanitizeText(text));
                }
    
                function addLink(url, text) {
                    var key;
                    html.push('<a ');
                    if (angular.isFunction(attributes)) {
                        attributes = attributes(url);
                    }
                    if (angular.isObject(attributes)) {
                        for (key in attributes) {
                            html.push(key + '="' + attributes[key] + '" ');
                        }
                    } else {
                        attributes = {};
                    }
                    if (angular.isDefined(target) && !('target' in attributes)) {
                        html.push('target="',
                            target,
                            '" ');
                    }
                    html.push('href="',
                        url.replace(/"/g, '&quot;'),
                        '">');
                    addText(text);
                    html.push('</a>');
                }
            };
        }]);
    })(window, window.angular);;
    /*! RESOURCE: /scripts/angular_1.5.3/angular-animate.js */
    (function(window, angular, undefined) {
        'use strict';
        var noop = angular.noop;
        var copy = angular.copy;
        var extend = angular.extend;
        var jqLite = angular.element;
        var forEach = angular.forEach;
        var isArray = angular.isArray;
        var isString = angular.isString;
        var isObject = angular.isObject;
        var isUndefined = angular.isUndefined;
        var isDefined = angular.isDefined;
        var isFunction = angular.isFunction;
        var isElement = angular.isElement;
        var ELEMENT_NODE = 1;
        var COMMENT_NODE = 8;
        var ADD_CLASS_SUFFIX = '-add';
        var REMOVE_CLASS_SUFFIX = '-remove';
        var EVENT_CLASS_PREFIX = 'ng-';
        var ACTIVE_CLASS_SUFFIX = '-active';
        var PREPARE_CLASS_SUFFIX = '-prepare';
        var NG_ANIMATE_CLASSNAME = 'ng-animate';
        var NG_ANIMATE_CHILDREN_DATA = '$$ngAnimateChildren';
        var CSS_PREFIX = '',
            TRANSITION_PROP, TRANSITIONEND_EVENT, ANIMATION_PROP, ANIMATIONEND_EVENT;
        if (isUndefined(window.ontransitionend) && isDefined(window.onwebkittransitionend)) {
            CSS_PREFIX = '-webkit-';
            TRANSITION_PROP = 'WebkitTransition';
            TRANSITIONEND_EVENT = 'webkitTransitionEnd transitionend';
        } else {
            TRANSITION_PROP = 'transition';
            TRANSITIONEND_EVENT = 'transitionend';
        }
        if (isUndefined(window.onanimationend) && isDefined(window.onwebkitanimationend)) {
            CSS_PREFIX = '-webkit-';
            ANIMATION_PROP = 'WebkitAnimation';
            ANIMATIONEND_EVENT = 'webkitAnimationEnd animationend';
        } else {
            ANIMATION_PROP = 'animation';
            ANIMATIONEND_EVENT = 'animationend';
        }
        var DURATION_KEY = 'Duration';
        var PROPERTY_KEY = 'Property';
        var DELAY_KEY = 'Delay';
        var TIMING_KEY = 'TimingFunction';
        var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount';
        var ANIMATION_PLAYSTATE_KEY = 'PlayState';
        var SAFE_FAST_FORWARD_DURATION_VALUE = 9999;
        var ANIMATION_DELAY_PROP = ANIMATION_PROP + DELAY_KEY;
        var ANIMATION_DURATION_PROP = ANIMATION_PROP + DURATION_KEY;
        var TRANSITION_DELAY_PROP = TRANSITION_PROP + DELAY_KEY;
        var TRANSITION_DURATION_PROP = TRANSITION_PROP + DURATION_KEY;
        var isPromiseLike = function(p) {
            return p && p.then ? true : false;
        };
        var ngMinErr = angular.$$minErr('ng');
    
        function assertArg(arg, name, reason) {
            if (!arg) {
                throw ngMinErr('areq', "Argument '{0}' is {1}", (name || '?'), (reason || "required"));
            }
            return arg;
        }
    
        function mergeClasses(a, b) {
            if (!a && !b) return '';
            if (!a) return b;
            if (!b) return a;
            if (isArray(a)) a = a.join(' ');
            if (isArray(b)) b = b.join(' ');
            return a + ' ' + b;
        }
    
        function packageStyles(options) {
            var styles = {};
            if (options && (options.to || options.from)) {
                styles.to = options.to;
                styles.from = options.from;
            }
            return styles;
        }
    
        function pendClasses(classes, fix, isPrefix) {
            var className = '';
            classes = isArray(classes) ?
                classes :
                classes && isString(classes) && classes.length ?
                classes.split(/\s+/) :
                [];
            forEach(classes, function(klass, i) {
                if (klass && klass.length > 0) {
                    className += (i > 0) ? ' ' : '';
                    className += isPrefix ? fix + klass :
                        klass + fix;
                }
            });
            return className;
        }
    
        function removeFromArray(arr, val) {
            var index = arr.indexOf(val);
            if (val >= 0) {
                arr.splice(index, 1);
            }
        }
    
        function stripCommentsFromElement(element) {
            if (element instanceof jqLite) {
                switch (element.length) {
                    case 0:
                        return [];
                        break;
                    case 1:
                        if (element[0].nodeType === ELEMENT_NODE) {
                            return element;
                        }
                        break;
                    default:
                        return jqLite(extractElementNode(element));
                        break;
                }
            }
            if (element.nodeType === ELEMENT_NODE) {
                return jqLite(element);
            }
        }
    
        function extractElementNode(element) {
            if (!element[0]) return element;
            for (var i = 0; i < element.length; i++) {
                var elm = element[i];
                if (elm.nodeType == ELEMENT_NODE) {
                    return elm;
                }
            }
        }
    
        function $$addClass($$jqLite, element, className) {
            forEach(element, function(elm) {
                $$jqLite.addClass(elm, className);
            });
        }
    
        function $$removeClass($$jqLite, element, className) {
            forEach(element, function(elm) {
                $$jqLite.removeClass(elm, className);
            });
        }
    
        function applyAnimationClassesFactory($$jqLite) {
            return function(element, options) {
                if (options.addClass) {
                    $$addClass($$jqLite, element, options.addClass);
                    options.addClass = null;
                }
                if (options.removeClass) {
                    $$removeClass($$jqLite, element, options.removeClass);
                    options.removeClass = null;
                }
            }
        }
    
        function prepareAnimationOptions(options) {
            options = options || {};
            if (!options.$$prepared) {
                var domOperation = options.domOperation || noop;
                options.domOperation = function() {
                    options.$$domOperationFired = true;
                    domOperation();
                    domOperation = noop;
                };
                options.$$prepared = true;
            }
            return options;
        }
    
        function applyAnimationStyles(element, options) {
            applyAnimationFromStyles(element, options);
            applyAnimationToStyles(element, options);
        }
    
        function applyAnimationFromStyles(element, options) {
            if (options.from) {
                element.css(options.from);
                options.from = null;
            }
        }
    
        function applyAnimationToStyles(element, options) {
            if (options.to) {
                element.css(options.to);
                options.to = null;
            }
        }
    
        function mergeAnimationDetails(element, oldAnimation, newAnimation) {
            var target = oldAnimation.options || {};
            var newOptions = newAnimation.options || {};
            var toAdd = (target.addClass || '') + ' ' + (newOptions.addClass || '');
            var toRemove = (target.removeClass || '') + ' ' + (newOptions.removeClass || '');
            var classes = resolveElementClasses(element.attr('class'), toAdd, toRemove);
            if (newOptions.preparationClasses) {
                target.preparationClasses = concatWithSpace(newOptions.preparationClasses, target.preparationClasses);
                delete newOptions.preparationClasses;
            }
            var realDomOperation = target.domOperation !== noop ? target.domOperation : null;
            extend(target, newOptions);
            if (realDomOperation) {
                target.domOperation = realDomOperation;
            }
            if (classes.addClass) {
                target.addClass = classes.addClass;
            } else {
                target.addClass = null;
            }
            if (classes.removeClass) {
                target.removeClass = classes.removeClass;
            } else {
                target.removeClass = null;
            }
            oldAnimation.addClass = target.addClass;
            oldAnimation.removeClass = target.removeClass;
            return target;
        }
    
        function resolveElementClasses(existing, toAdd, toRemove) {
            var ADD_CLASS = 1;
            var REMOVE_CLASS = -1;
            var flags = {};
            existing = splitClassesToLookup(existing);
            toAdd = splitClassesToLookup(toAdd);
            forEach(toAdd, function(value, key) {
                flags[key] = ADD_CLASS;
            });
            toRemove = splitClassesToLookup(toRemove);
            forEach(toRemove, function(value, key) {
                flags[key] = flags[key] === ADD_CLASS ? null : REMOVE_CLASS;
            });
            var classes = {
                addClass: '',
                removeClass: ''
            };
            forEach(flags, function(val, klass) {
                var prop, allow;
                if (val === ADD_CLASS) {
                    prop = 'addClass';
                    allow = !existing[klass];
                } else if (val === REMOVE_CLASS) {
                    prop = 'removeClass';
                    allow = existing[klass];
                }
                if (allow) {
                    if (classes[prop].length) {
                        classes[prop] += ' ';
                    }
                    classes[prop] += klass;
                }
            });
    
            function splitClassesToLookup(classes) {
                if (isString(classes)) {
                    classes = classes.split(' ');
                }
                var obj = {};
                forEach(classes, function(klass) {
                    if (klass.length) {
                        obj[klass] = true;
                    }
                });
                return obj;
            }
            return classes;
        }
    
        function getDomNode(element) {
            return (element instanceof angular.element) ? element[0] : element;
        }
    
        function applyGeneratedPreparationClasses(element, event, options) {
            var classes = '';
            if (event) {
                classes = pendClasses(event, EVENT_CLASS_PREFIX, true);
            }
            if (options.addClass) {
                classes = concatWithSpace(classes, pendClasses(options.addClass, ADD_CLASS_SUFFIX));
            }
            if (options.removeClass) {
                classes = concatWithSpace(classes, pendClasses(options.removeClass, REMOVE_CLASS_SUFFIX));
            }
            if (classes.length) {
                options.preparationClasses = classes;
                element.addClass(classes);
            }
        }
    
        function clearGeneratedClasses(element, options) {
            if (options.preparationClasses) {
                element.removeClass(options.preparationClasses);
                options.preparationClasses = null;
            }
            if (options.activeClasses) {
                element.removeClass(options.activeClasses);
                options.activeClasses = null;
            }
        }
    
        function blockTransitions(node, duration) {
            var value = duration ? '-' + duration + 's' : '';
            applyInlineStyle(node, [TRANSITION_DELAY_PROP, value]);
            return [TRANSITION_DELAY_PROP, value];
        }
    
        function blockKeyframeAnimations(node, applyBlock) {
            var value = applyBlock ? 'paused' : '';
            var key = ANIMATION_PROP + ANIMATION_PLAYSTATE_KEY;
            applyInlineStyle(node, [key, value]);
            return [key, value];
        }
    
        function applyInlineStyle(node, styleTuple) {
            var prop = styleTuple[0];
            var value = styleTuple[1];
            node.style[prop] = value;
        }
    
        function concatWithSpace(a, b) {
            if (!a) return b;
            if (!b) return a;
            return a + ' ' + b;
        }
        var $$rAFSchedulerFactory = ['$$rAF', function($$rAF) {
            var queue, cancelFn;
    
            function scheduler(tasks) {
                queue = queue.concat(tasks);
                nextTick();
            }
            queue = scheduler.queue = [];
            scheduler.waitUntilQuiet = function(fn) {
                if (cancelFn) cancelFn();
                cancelFn = $$rAF(function() {
                    cancelFn = null;
                    fn();
                    nextTick();
                });
            };
            return scheduler;
    
            function nextTick() {
                if (!queue.length) return;
                var items = queue.shift();
                for (var i = 0; i < items.length; i++) {
                    items[i]();
                }
                if (!cancelFn) {
                    $$rAF(function() {
                        if (!cancelFn) nextTick();
                    });
                }
            }
        }];
        var $$AnimateChildrenDirective = ['$interpolate', function($interpolate) {
            return {
                link: function(scope, element, attrs) {
                    var val = attrs.ngAnimateChildren;
                    if (angular.isString(val) && val.length === 0) {
                        element.data(NG_ANIMATE_CHILDREN_DATA, true);
                    } else {
                        setData($interpolate(val)(scope));
                        attrs.$observe('ngAnimateChildren', setData);
                    }
    
                    function setData(value) {
                        value = value === 'on' || value === 'true';
                        element.data(NG_ANIMATE_CHILDREN_DATA, value);
                    }
                }
            };
        }];
        var ANIMATE_TIMER_KEY = '$$animateCss';
        var ONE_SECOND = 1000;
        var BASE_TEN = 10;
        var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;
        var CLOSING_TIME_BUFFER = 1.5;
        var DETECT_CSS_PROPERTIES = {
            transitionDuration: TRANSITION_DURATION_PROP,
            transitionDelay: TRANSITION_DELAY_PROP,
            transitionProperty: TRANSITION_PROP + PROPERTY_KEY,
            animationDuration: ANIMATION_DURATION_PROP,
            animationDelay: ANIMATION_DELAY_PROP,
            animationIterationCount: ANIMATION_PROP + ANIMATION_ITERATION_COUNT_KEY
        };
        var DETECT_STAGGER_CSS_PROPERTIES = {
            transitionDuration: TRANSITION_DURATION_PROP,
            transitionDelay: TRANSITION_DELAY_PROP,
            animationDuration: ANIMATION_DURATION_PROP,
            animationDelay: ANIMATION_DELAY_PROP
        };
    
        function getCssKeyframeDurationStyle(duration) {
            return [ANIMATION_DURATION_PROP, duration + 's'];
        }
    
        function getCssDelayStyle(delay, isKeyframeAnimation) {
            var prop = isKeyframeAnimation ? ANIMATION_DELAY_PROP : TRANSITION_DELAY_PROP;
            return [prop, delay + 's'];
        }
    
        function computeCssStyles($window, element, properties) {
            var styles = Object.create(null);
            var detectedStyles = $window.getComputedStyle(element) || {};
            forEach(properties, function(formalStyleName, actualStyleName) {
                var val = detectedStyles[formalStyleName];
                if (val) {
                    var c = val.charAt(0);
                    if (c === '-' || c === '+' || c >= 0) {
                        val = parseMaxTime(val);
                    }
                    if (val === 0) {
                        val = null;
                    }
                    styles[actualStyleName] = val;
                }
            });
            return styles;
        }
    
        function parseMaxTime(str) {
            var maxValue = 0;
            var values = str.split(/\s*,\s*/);
            forEach(values, function(value) {
                if (value.charAt(value.length - 1) == 's') {
                    value = value.substring(0, value.length - 1);
                }
                value = parseFloat(value) || 0;
                maxValue = maxValue ? Math.max(value, maxValue) : value;
            });
            return maxValue;
        }
    
        function truthyTimingValue(val) {
            return val === 0 || val != null;
        }
    
        function getCssTransitionDurationStyle(duration, applyOnlyDuration) {
            var style = TRANSITION_PROP;
            var value = duration + 's';
            if (applyOnlyDuration) {
                style += DURATION_KEY;
            } else {
                value += ' linear all';
            }
            return [style, value];
        }
    
        function createLocalCacheLookup() {
            var cache = Object.create(null);
            return {
                flush: function() {
                    cache = Object.create(null);
                },
                count: function(key) {
                    var entry = cache[key];
                    return entry ? entry.total : 0;
                },
                get: function(key) {
                    var entry = cache[key];
                    return entry && entry.value;
                },
                put: function(key, value) {
                    if (!cache[key]) {
                        cache[key] = {
                            total: 1,
                            value: value
                        };
                    } else {
                        cache[key].total++;
                    }
                }
            };
        }
    
        function registerRestorableStyles(backup, node, properties) {
            forEach(properties, function(prop) {
                backup[prop] = isDefined(backup[prop]) ?
                    backup[prop] :
                    node.style.getPropertyValue(prop);
            });
        }
        var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
            var gcsLookup = createLocalCacheLookup();
            var gcsStaggerLookup = createLocalCacheLookup();
            this.$get = ['$window', '$$jqLite', '$$AnimateRunner', '$timeout',
                '$$forceReflow', '$sniffer', '$$rAFScheduler', '$$animateQueue',
                function($window, $$jqLite, $$AnimateRunner, $timeout,
                    $$forceReflow, $sniffer, $$rAFScheduler, $$animateQueue) {
                    var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
                    var parentCounter = 0;
    
                    function gcsHashFn(node, extraClasses) {
                        var KEY = "$$ngAnimateParentKey";
                        var parentNode = node.parentNode;
                        var parentID = parentNode[KEY] || (parentNode[KEY] = ++parentCounter);
                        return parentID + '-' + node.getAttribute('class') + '-' + extraClasses;
                    }
    
                    function computeCachedCssStyles(node, className, cacheKey, properties) {
                        var timings = gcsLookup.get(cacheKey);
                        if (!timings) {
                            timings = computeCssStyles($window, node, properties);
                            if (timings.animationIterationCount === 'infinite') {
                                timings.animationIterationCount = 1;
                            }
                        }
                        gcsLookup.put(cacheKey, timings);
                        return timings;
                    }
    
                    function computeCachedCssStaggerStyles(node, className, cacheKey, properties) {
                        var stagger;
                        if (gcsLookup.count(cacheKey) > 0) {
                            stagger = gcsStaggerLookup.get(cacheKey);
                            if (!stagger) {
                                var staggerClassName = pendClasses(className, '-stagger');
                                $$jqLite.addClass(node, staggerClassName);
                                stagger = computeCssStyles($window, node, properties);
                                stagger.animationDuration = Math.max(stagger.animationDuration, 0);
                                stagger.transitionDuration = Math.max(stagger.transitionDuration, 0);
                                $$jqLite.removeClass(node, staggerClassName);
                                gcsStaggerLookup.put(cacheKey, stagger);
                            }
                        }
                        return stagger || {};
                    }
                    var cancelLastRAFRequest;
                    var rafWaitQueue = [];
    
                    function waitUntilQuiet(callback) {
                        rafWaitQueue.push(callback);
                        $$rAFScheduler.waitUntilQuiet(function() {
                            gcsLookup.flush();
                            gcsStaggerLookup.flush();
                            var pageWidth = $$forceReflow();
                            for (var i = 0; i < rafWaitQueue.length; i++) {
                                rafWaitQueue[i](pageWidth);
                            }
                            rafWaitQueue.length = 0;
                        });
                    }
    
                    function computeTimings(node, className, cacheKey) {
                        var timings = computeCachedCssStyles(node, className, cacheKey, DETECT_CSS_PROPERTIES);
                        var aD = timings.animationDelay;
                        var tD = timings.transitionDelay;
                        timings.maxDelay = aD && tD ?
                            Math.max(aD, tD) :
                            (aD || tD);
                        timings.maxDuration = Math.max(
                            timings.animationDuration * timings.animationIterationCount,
                            timings.transitionDuration);
                        return timings;
                    }
                    return function init(element, initialOptions) {
                        var options = initialOptions || {};
                        if (!options.$$prepared) {
                            options = prepareAnimationOptions(copy(options));
                        }
                        var restoreStyles = {};
                        var node = getDomNode(element);
                        if (!node ||
                            !node.parentNode ||
                            !$$animateQueue.enabled()) {
                            return closeAndReturnNoopAnimator();
                        }
                        var temporaryStyles = [];
                        var classes = element.attr('class');
                        var styles = packageStyles(options);
                        var animationClosed;
                        var animationPaused;
                        var animationCompleted;
                        var runner;
                        var runnerHost;
                        var maxDelay;
                        var maxDelayTime;
                        var maxDuration;
                        var maxDurationTime;
                        var startTime;
                        var events = [];
                        if (options.duration === 0 || (!$sniffer.animations && !$sniffer.transitions)) {
                            return closeAndReturnNoopAnimator();
                        }
                        var method = options.event && isArray(options.event) ?
                            options.event.join(' ') :
                            options.event;
                        var isStructural = method && options.structural;
                        var structuralClassName = '';
                        var addRemoveClassName = '';
                        if (isStructural) {
                            structuralClassName = pendClasses(method, EVENT_CLASS_PREFIX, true);
                        } else if (method) {
                            structuralClassName = method;
                        }
                        if (options.addClass) {
                            addRemoveClassName += pendClasses(options.addClass, ADD_CLASS_SUFFIX);
                        }
                        if (options.removeClass) {
                            if (addRemoveClassName.length) {
                                addRemoveClassName += ' ';
                            }
                            addRemoveClassName += pendClasses(options.removeClass, REMOVE_CLASS_SUFFIX);
                        }
                        if (options.applyClassesEarly && addRemoveClassName.length) {
                            applyAnimationClasses(element, options);
                        }
                        var preparationClasses = [structuralClassName, addRemoveClassName].join(' ').trim();
                        var fullClassName = classes + ' ' + preparationClasses;
                        var activeClasses = pendClasses(preparationClasses, ACTIVE_CLASS_SUFFIX);
                        var hasToStyles = styles.to && Object.keys(styles.to).length > 0;
                        var containsKeyframeAnimation = (options.keyframeStyle || '').length > 0;
                        if (!containsKeyframeAnimation &&
                            !hasToStyles &&
                            !preparationClasses) {
                            return closeAndReturnNoopAnimator();
                        }
                        var cacheKey, stagger;
                        if (options.stagger > 0) {
                            var staggerVal = parseFloat(options.stagger);
                            stagger = {
                                transitionDelay: staggerVal,
                                animationDelay: staggerVal,
                                transitionDuration: 0,
                                animationDuration: 0
                            };
                        } else {
                            cacheKey = gcsHashFn(node, fullClassName);
                            stagger = computeCachedCssStaggerStyles(node, preparationClasses, cacheKey, DETECT_STAGGER_CSS_PROPERTIES);
                        }
                        if (!options.$$skipPreparationClasses) {
                            $$jqLite.addClass(element, preparationClasses);
                        }
                        var applyOnlyDuration;
                        if (options.transitionStyle) {
                            var transitionStyle = [TRANSITION_PROP, options.transitionStyle];
                            applyInlineStyle(node, transitionStyle);
                            temporaryStyles.push(transitionStyle);
                        }
                        if (options.duration >= 0) {
                            applyOnlyDuration = node.style[TRANSITION_PROP].length > 0;
                            var durationStyle = getCssTransitionDurationStyle(options.duration, applyOnlyDuration);
                            applyInlineStyle(node, durationStyle);
                            temporaryStyles.push(durationStyle);
                        }
                        if (options.keyframeStyle) {
                            var keyframeStyle = [ANIMATION_PROP, options.keyframeStyle];
                            applyInlineStyle(node, keyframeStyle);
                            temporaryStyles.push(keyframeStyle);
                        }
                        var itemIndex = stagger ?
                            options.staggerIndex >= 0 ?
                            options.staggerIndex :
                            gcsLookup.count(cacheKey) :
                            0;
                        var isFirst = itemIndex === 0;
                        if (isFirst && !options.skipBlocking) {
                            blockTransitions(node, SAFE_FAST_FORWARD_DURATION_VALUE);
                        }
                        var timings = computeTimings(node, fullClassName, cacheKey);
                        var relativeDelay = timings.maxDelay;
                        maxDelay = Math.max(relativeDelay, 0);
                        maxDuration = timings.maxDuration;
                        var flags = {};
                        flags.hasTransitions = timings.transitionDuration > 0;
                        flags.hasAnimations = timings.animationDuration > 0;
                        flags.hasTransitionAll = flags.hasTransitions && timings.transitionProperty == 'all';
                        flags.applyTransitionDuration = hasToStyles && (
                            (flags.hasTransitions && !flags.hasTransitionAll) ||
                            (flags.hasAnimations && !flags.hasTransitions));
                        flags.applyAnimationDuration = options.duration && flags.hasAnimations;
                        flags.applyTransitionDelay = truthyTimingValue(options.delay) && (flags.applyTransitionDuration || flags.hasTransitions);
                        flags.applyAnimationDelay = truthyTimingValue(options.delay) && flags.hasAnimations;
                        flags.recalculateTimingStyles = addRemoveClassName.length > 0;
                        if (flags.applyTransitionDuration || flags.applyAnimationDuration) {
                            maxDuration = options.duration ? parseFloat(options.duration) : maxDuration;
                            if (flags.applyTransitionDuration) {
                                flags.hasTransitions = true;
                                timings.transitionDuration = maxDuration;
                                applyOnlyDuration = node.style[TRANSITION_PROP + PROPERTY_KEY].length > 0;
                                temporaryStyles.push(getCssTransitionDurationStyle(maxDuration, applyOnlyDuration));
                            }
                            if (flags.applyAnimationDuration) {
                                flags.hasAnimations = true;
                                timings.animationDuration = maxDuration;
                                temporaryStyles.push(getCssKeyframeDurationStyle(maxDuration));
                            }
                        }
                        if (maxDuration === 0 && !flags.recalculateTimingStyles) {
                            return closeAndReturnNoopAnimator();
                        }
                        if (options.delay != null) {
                            var delayStyle;
                            if (typeof options.delay !== "boolean") {
                                delayStyle = parseFloat(options.delay);
                                maxDelay = Math.max(delayStyle, 0);
                            }
                            if (flags.applyTransitionDelay) {
                                temporaryStyles.push(getCssDelayStyle(delayStyle));
                            }
                            if (flags.applyAnimationDelay) {
                                temporaryStyles.push(getCssDelayStyle(delayStyle, true));
                            }
                        }
                        if (options.duration == null && timings.transitionDuration > 0) {
                            flags.recalculateTimingStyles = flags.recalculateTimingStyles || isFirst;
                        }
                        maxDelayTime = maxDelay * ONE_SECOND;
                        maxDurationTime = maxDuration * ONE_SECOND;
                        if (!options.skipBlocking) {
                            flags.blockTransition = timings.transitionDuration > 0;
                            flags.blockKeyframeAnimation = timings.animationDuration > 0 &&
                                stagger.animationDelay > 0 &&
                                stagger.animationDuration === 0;
                        }
                        if (options.from) {
                            if (options.cleanupStyles) {
                                registerRestorableStyles(restoreStyles, node, Object.keys(options.from));
                            }
                            applyAnimationFromStyles(element, options);
                        }
                        if (flags.blockTransition || flags.blockKeyframeAnimation) {
                            applyBlocking(maxDuration);
                        } else if (!options.skipBlocking) {
                            blockTransitions(node, false);
                        }
                        return {
                            $$willAnimate: true,
                            end: endFn,
                            start: function() {
                                if (animationClosed) return;
                                runnerHost = {
                                    end: endFn,
                                    cancel: cancelFn,
                                    resume: null,
                                    pause: null
                                };
                                runner = new $$AnimateRunner(runnerHost);
                                waitUntilQuiet(start);
                                return runner;
                            }
                        };
    
                        function endFn() {
                            close();
                        }
    
                        function cancelFn() {
                            close(true);
                        }
    
                        function close(rejected) {
                            if (animationClosed || (animationCompleted && animationPaused)) return;
                            animationClosed = true;
                            animationPaused = false;
                            if (!options.$$skipPreparationClasses) {
                                $$jqLite.removeClass(element, preparationClasses);
                            }
                            $$jqLite.removeClass(element, activeClasses);
                            blockKeyframeAnimations(node, false);
                            blockTransitions(node, false);
                            forEach(temporaryStyles, function(entry) {
                                node.style[entry[0]] = '';
                            });
                            applyAnimationClasses(element, options);
                            applyAnimationStyles(element, options);
                            if (Object.keys(restoreStyles).length) {
                                forEach(restoreStyles, function(value, prop) {
                                    value ? node.style.setProperty(prop, value) :
                                        node.style.removeProperty(prop);
                                });
                            }
                            if (options.onDone) {
                                options.onDone();
                            }
                            if (events && events.length) {
                                element.off(events.join(' '), onAnimationProgress);
                            }
                            var animationTimerData = element.data(ANIMATE_TIMER_KEY);
                            if (animationTimerData) {
                                $timeout.cancel(animationTimerData[0].timer);
                                element.removeData(ANIMATE_TIMER_KEY);
                            }
                            if (runner) {
                                runner.complete(!rejected);
                            }
                        }
    
                        function applyBlocking(duration) {
                            if (flags.blockTransition) {
                                blockTransitions(node, duration);
                            }
                            if (flags.blockKeyframeAnimation) {
                                blockKeyframeAnimations(node, !!duration);
                            }
                        }
    
                        function closeAndReturnNoopAnimator() {
                            runner = new $$AnimateRunner({
                                end: endFn,
                                cancel: cancelFn
                            });
                            waitUntilQuiet(noop);
                            close();
                            return {
                                $$willAnimate: false,
                                start: function() {
                                    return runner;
                                },
                                end: endFn
                            };
                        }
    
                        function onAnimationProgress(event) {
                            event.stopPropagation();
                            var ev = event.originalEvent || event;
                            var timeStamp = ev.$manualTimeStamp || Date.now();
                            var elapsedTime = parseFloat(ev.elapsedTime.toFixed(ELAPSED_TIME_MAX_DECIMAL_PLACES));
                            if (Math.max(timeStamp - startTime, 0) >= maxDelayTime && elapsedTime >= maxDuration) {
                                animationCompleted = true;
                                close();
                            }
                        }
    
                        function start() {
                            if (animationClosed) return;
                            if (!node.parentNode) {
                                close();
                                return;
                            }
                            var playPause = function(playAnimation) {
                                if (!animationCompleted) {
                                    animationPaused = !playAnimation;
                                    if (timings.animationDuration) {
                                        var value = blockKeyframeAnimations(node, animationPaused);
                                        animationPaused
                                            ?
                                            temporaryStyles.push(value) :
                                            removeFromArray(temporaryStyles, value);
                                    }
                                } else if (animationPaused && playAnimation) {
                                    animationPaused = false;
                                    close();
                                }
                            };
                            var maxStagger = itemIndex > 0 &&
                                ((timings.transitionDuration && stagger.transitionDuration === 0) ||
                                    (timings.animationDuration && stagger.animationDuration === 0)) &&
                                Math.max(stagger.animationDelay, stagger.transitionDelay);
                            if (maxStagger) {
                                $timeout(triggerAnimationStart,
                                    Math.floor(maxStagger * itemIndex * ONE_SECOND),
                                    false);
                            } else {
                                triggerAnimationStart();
                            }
                            runnerHost.resume = function() {
                                playPause(true);
                            };
                            runnerHost.pause = function() {
                                playPause(false);
                            };
    
                            function triggerAnimationStart() {
                                if (animationClosed) return;
                                applyBlocking(false);
                                forEach(temporaryStyles, function(entry) {
                                    var key = entry[0];
                                    var value = entry[1];
                                    node.style[key] = value;
                                });
                                applyAnimationClasses(element, options);
                                $$jqLite.addClass(element, activeClasses);
                                if (flags.recalculateTimingStyles) {
                                    fullClassName = node.className + ' ' + preparationClasses;
                                    cacheKey = gcsHashFn(node, fullClassName);
                                    timings = computeTimings(node, fullClassName, cacheKey);
                                    relativeDelay = timings.maxDelay;
                                    maxDelay = Math.max(relativeDelay, 0);
                                    maxDuration = timings.maxDuration;
                                    if (maxDuration === 0) {
                                        close();
                                        return;
                                    }
                                    flags.hasTransitions = timings.transitionDuration > 0;
                                    flags.hasAnimations = timings.animationDuration > 0;
                                }
                                if (flags.applyAnimationDelay) {
                                    relativeDelay = typeof options.delay !== "boolean" && truthyTimingValue(options.delay) ?
                                        parseFloat(options.delay) :
                                        relativeDelay;
                                    maxDelay = Math.max(relativeDelay, 0);
                                    timings.animationDelay = relativeDelay;
                                    delayStyle = getCssDelayStyle(relativeDelay, true);
                                    temporaryStyles.push(delayStyle);
                                    node.style[delayStyle[0]] = delayStyle[1];
                                }
                                maxDelayTime = maxDelay * ONE_SECOND;
                                maxDurationTime = maxDuration * ONE_SECOND;
                                if (options.easing) {
                                    var easeProp, easeVal = options.easing;
                                    if (flags.hasTransitions) {
                                        easeProp = TRANSITION_PROP + TIMING_KEY;
                                        temporaryStyles.push([easeProp, easeVal]);
                                        node.style[easeProp] = easeVal;
                                    }
                                    if (flags.hasAnimations) {
                                        easeProp = ANIMATION_PROP + TIMING_KEY;
                                        temporaryStyles.push([easeProp, easeVal]);
                                        node.style[easeProp] = easeVal;
                                    }
                                }
                                if (timings.transitionDuration) {
                                    events.push(TRANSITIONEND_EVENT);
                                }
                                if (timings.animationDuration) {
                                    events.push(ANIMATIONEND_EVENT);
                                }
                                startTime = Date.now();
                                var timerTime = maxDelayTime + CLOSING_TIME_BUFFER * maxDurationTime;
                                var endTime = startTime + timerTime;
                                var animationsData = element.data(ANIMATE_TIMER_KEY) || [];
                                var setupFallbackTimer = true;
                                if (animationsData.length) {
                                    var currentTimerData = animationsData[0];
                                    setupFallbackTimer = endTime > currentTimerData.expectedEndTime;
                                    if (setupFallbackTimer) {
                                        $timeout.cancel(currentTimerData.timer);
                                    } else {
                                        animationsData.push(close);
                                    }
                                }
                                if (setupFallbackTimer) {
                                    var timer = $timeout(onAnimationExpired, timerTime, false);
                                    animationsData[0] = {
                                        timer: timer,
                                        expectedEndTime: endTime
                                    };
                                    animationsData.push(close);
                                    element.data(ANIMATE_TIMER_KEY, animationsData);
                                }
                                if (events.length) {
                                    element.on(events.join(' '), onAnimationProgress);
                                }
                                if (options.to) {
                                    if (options.cleanupStyles) {
                                        registerRestorableStyles(restoreStyles, node, Object.keys(options.to));
                                    }
                                    applyAnimationToStyles(element, options);
                                }
                            }
    
                            function onAnimationExpired() {
                                var animationsData = element.data(ANIMATE_TIMER_KEY);
                                if (animationsData) {
                                    for (var i = 1; i < animationsData.length; i++) {
                                        animationsData[i]();
                                    }
                                    element.removeData(ANIMATE_TIMER_KEY);
                                }
                            }
                        }
                    };
                }
            ];
        }];
        var $$AnimateCssDriverProvider = ['$$animationProvider', function($$animationProvider) {
            $$animationProvider.drivers.push('$$animateCssDriver');
            var NG_ANIMATE_SHIM_CLASS_NAME = 'ng-animate-shim';
            var NG_ANIMATE_ANCHOR_CLASS_NAME = 'ng-anchor';
            var NG_OUT_ANCHOR_CLASS_NAME = 'ng-anchor-out';
            var NG_IN_ANCHOR_CLASS_NAME = 'ng-anchor-in';
    
            function isDocumentFragment(node) {
                return node.parentNode && node.parentNode.nodeType === 11;
            }
            this.$get = ['$animateCss', '$rootScope', '$$AnimateRunner', '$rootElement', '$sniffer', '$$jqLite', '$document',
                function($animateCss, $rootScope, $$AnimateRunner, $rootElement, $sniffer, $$jqLite, $document) {
                    if (!$sniffer.animations && !$sniffer.transitions) return noop;
                    var bodyNode = $document[0].body;
                    var rootNode = getDomNode($rootElement);
                    var rootBodyElement = jqLite(
                        isDocumentFragment(rootNode) || bodyNode.contains(rootNode) ? rootNode : bodyNode
                    );
                    var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
                    return function initDriverFn(animationDetails) {
                        return animationDetails.from && animationDetails.to ?
                            prepareFromToAnchorAnimation(animationDetails.from,
                                animationDetails.to,
                                animationDetails.classes,
                                animationDetails.anchors) :
                            prepareRegularAnimation(animationDetails);
                    };
    
                    function filterCssClasses(classes) {
                        return classes.replace(/\bng-\S+\b/g, '');
                    }
    
                    function getUniqueValues(a, b) {
                        if (isString(a)) a = a.split(' ');
                        if (isString(b)) b = b.split(' ');
                        return a.filter(function(val) {
                            return b.indexOf(val) === -1;
                        }).join(' ');
                    }
    
                    function prepareAnchoredAnimation(classes, outAnchor, inAnchor) {
                        var clone = jqLite(getDomNode(outAnchor).cloneNode(true));
                        var startingClasses = filterCssClasses(getClassVal(clone));
                        outAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME);
                        inAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME);
                        clone.addClass(NG_ANIMATE_ANCHOR_CLASS_NAME);
                        rootBodyElement.append(clone);
                        var animatorIn, animatorOut = prepareOutAnimation();
                        if (!animatorOut) {
                            animatorIn = prepareInAnimation();
                            if (!animatorIn) {
                                return end();
                            }
                        }
                        var startingAnimator = animatorOut || animatorIn;
                        return {
                            start: function() {
                                var runner;
                                var currentAnimation = startingAnimator.start();
                                currentAnimation.done(function() {
                                    currentAnimation = null;
                                    if (!animatorIn) {
                                        animatorIn = prepareInAnimation();
                                        if (animatorIn) {
                                            currentAnimation = animatorIn.start();
                                            currentAnimation.done(function() {
                                                currentAnimation = null;
                                                end();
                                                runner.complete();
                                            });
                                            return currentAnimation;
                                        }
                                    }
                                    end();
                                    runner.complete();
                                });
                                runner = new $$AnimateRunner({
                                    end: endFn,
                                    cancel: endFn
                                });
                                return runner;
    
                                function endFn() {
                                    if (currentAnimation) {
                                        currentAnimation.end();
                                    }
                                }
                            }
                        };
    
                        function calculateAnchorStyles(anchor) {
                            var styles = {};
                            var coords = getDomNode(anchor).getBoundingClientRect();
                            forEach(['width', 'height', 'top', 'left'], function(key) {
                                var value = coords[key];
                                switch (key) {
                                    case 'top':
                                        value += bodyNode.scrollTop;
                                        break;
                                    case 'left':
                                        value += bodyNode.scrollLeft;
                                        break;
                                }
                                styles[key] = Math.floor(value) + 'px';
                            });
                            return styles;
                        }
    
                        function prepareOutAnimation() {
                            var animator = $animateCss(clone, {
                                addClass: NG_OUT_ANCHOR_CLASS_NAME,
                                delay: true,
                                from: calculateAnchorStyles(outAnchor)
                            });
                            return animator.$$willAnimate ? animator : null;
                        }
    
                        function getClassVal(element) {
                            return element.attr('class') || '';
                        }
    
                        function prepareInAnimation() {
                            var endingClasses = filterCssClasses(getClassVal(inAnchor));
                            var toAdd = getUniqueValues(endingClasses, startingClasses);
                            var toRemove = getUniqueValues(startingClasses, endingClasses);
                            var animator = $animateCss(clone, {
                                to: calculateAnchorStyles(inAnchor),
                                addClass: NG_IN_ANCHOR_CLASS_NAME + ' ' + toAdd,
                                removeClass: NG_OUT_ANCHOR_CLASS_NAME + ' ' + toRemove,
                                delay: true
                            });
                            return animator.$$willAnimate ? animator : null;
                        }
    
                        function end() {
                            clone.remove();
                            outAnchor.removeClass(NG_ANIMATE_SHIM_CLASS_NAME);
                            inAnchor.removeClass(NG_ANIMATE_SHIM_CLASS_NAME);
                        }
                    }
    
                    function prepareFromToAnchorAnimation(from, to, classes, anchors) {
                        var fromAnimation = prepareRegularAnimation(from, noop);
                        var toAnimation = prepareRegularAnimation(to, noop);
                        var anchorAnimations = [];
                        forEach(anchors, function(anchor) {
                            var outElement = anchor['out'];
                            var inElement = anchor['in'];
                            var animator = prepareAnchoredAnimation(classes, outElement, inElement);
                            if (animator) {
                                anchorAnimations.push(animator);
                            }
                        });
                        if (!fromAnimation && !toAnimation && anchorAnimations.length === 0) return;
                        return {
                            start: function() {
                                var animationRunners = [];
                                if (fromAnimation) {
                                    animationRunners.push(fromAnimation.start());
                                }
                                if (toAnimation) {
                                    animationRunners.push(toAnimation.start());
                                }
                                forEach(anchorAnimations, function(animation) {
                                    animationRunners.push(animation.start());
                                });
                                var runner = new $$AnimateRunner({
                                    end: endFn,
                                    cancel: endFn
                                });
                                $$AnimateRunner.all(animationRunners, function(status) {
                                    runner.complete(status);
                                });
                                return runner;
    
                                function endFn() {
                                    forEach(animationRunners, function(runner) {
                                        runner.end();
                                    });
                                }
                            }
                        };
                    }
    
                    function prepareRegularAnimation(animationDetails) {
                        var element = animationDetails.element;
                        var options = animationDetails.options || {};
                        if (animationDetails.structural) {
                            options.event = animationDetails.event;
                            options.structural = true;
                            options.applyClassesEarly = true;
                            if (animationDetails.event === 'leave') {
                                options.onDone = options.domOperation;
                            }
                        }
                        if (options.preparationClasses) {
                            options.event = concatWithSpace(options.event, options.preparationClasses);
                        }
                        var animator = $animateCss(element, options);
                        return animator.$$willAnimate ? animator : null;
                    }
                }
            ];
        }];
        var $$AnimateJsProvider = ['$animateProvider', function($animateProvider) {
            this.$get = ['$injector', '$$AnimateRunner', '$$jqLite',
                function($injector, $$AnimateRunner, $$jqLite) {
                    var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
                    return function(element, event, classes, options) {
                        var animationClosed = false;
                        if (arguments.length === 3 && isObject(classes)) {
                            options = classes;
                            classes = null;
                        }
                        options = prepareAnimationOptions(options);
                        if (!classes) {
                            classes = element.attr('class') || '';
                            if (options.addClass) {
                                classes += ' ' + options.addClass;
                            }
                            if (options.removeClass) {
                                classes += ' ' + options.removeClass;
                            }
                        }
                        var classesToAdd = options.addClass;
                        var classesToRemove = options.removeClass;
                        var animations = lookupAnimations(classes);
                        var before, after;
                        if (animations.length) {
                            var afterFn, beforeFn;
                            if (event == 'leave') {
                                beforeFn = 'leave';
                                afterFn = 'afterLeave';
                            } else {
                                beforeFn = 'before' + event.charAt(0).toUpperCase() + event.substr(1);
                                afterFn = event;
                            }
                            if (event !== 'enter' && event !== 'move') {
                                before = packageAnimations(element, event, options, animations, beforeFn);
                            }
                            after = packageAnimations(element, event, options, animations, afterFn);
                        }
                        if (!before && !after) return;
    
                        function applyOptions() {
                            options.domOperation();
                            applyAnimationClasses(element, options);
                        }
    
                        function close() {
                            animationClosed = true;
                            applyOptions();
                            applyAnimationStyles(element, options);
                        }
                        var runner;
                        return {
                            $$willAnimate: true,
                            end: function() {
                                if (runner) {
                                    runner.end();
                                } else {
                                    close();
                                    runner = new $$AnimateRunner();
                                    runner.complete(true);
                                }
                                return runner;
                            },
                            start: function() {
                                if (runner) {
                                    return runner;
                                }
                                runner = new $$AnimateRunner();
                                var closeActiveAnimations;
                                var chain = [];
                                if (before) {
                                    chain.push(function(fn) {
                                        closeActiveAnimations = before(fn);
                                    });
                                }
                                if (chain.length) {
                                    chain.push(function(fn) {
                                        applyOptions();
                                        fn(true);
                                    });
                                } else {
                                    applyOptions();
                                }
                                if (after) {
                                    chain.push(function(fn) {
                                        closeActiveAnimations = after(fn);
                                    });
                                }
                                runner.setHost({
                                    end: function() {
                                        endAnimations();
                                    },
                                    cancel: function() {
                                        endAnimations(true);
                                    }
                                });
                                $$AnimateRunner.chain(chain, onComplete);
                                return runner;
    
                                function onComplete(success) {
                                    close(success);
                                    runner.complete(success);
                                }
    
                                function endAnimations(cancelled) {
                                    if (!animationClosed) {
                                        (closeActiveAnimations || noop)(cancelled);
                                        onComplete(cancelled);
                                    }
                                }
                            }
                        };
    
                        function executeAnimationFn(fn, element, event, options, onDone) {
                            var args;
                            switch (event) {
                                case 'animate':
                                    args = [element, options.from, options.to, onDone];
                                    break;
                                case 'setClass':
                                    args = [element, classesToAdd, classesToRemove, onDone];
                                    break;
                                case 'addClass':
                                    args = [element, classesToAdd, onDone];
                                    break;
                                case 'removeClass':
                                    args = [element, classesToRemove, onDone];
                                    break;
                                default:
                                    args = [element, onDone];
                                    break;
                            }
                            args.push(options);
                            var value = fn.apply(fn, args);
                            if (value) {
                                if (isFunction(value.start)) {
                                    value = value.start();
                                }
                                if (value instanceof $$AnimateRunner) {
                                    value.done(onDone);
                                } else if (isFunction(value)) {
                                    return value;
                                }
                            }
                            return noop;
                        }
    
                        function groupEventedAnimations(element, event, options, animations, fnName) {
                            var operations = [];
                            forEach(animations, function(ani) {
                                var animation = ani[fnName];
                                if (!animation) return;
                                operations.push(function() {
                                    var runner;
                                    var endProgressCb;
                                    var resolved = false;
                                    var onAnimationComplete = function(rejected) {
                                        if (!resolved) {
                                            resolved = true;
                                            (endProgressCb || noop)(rejected);
                                            runner.complete(!rejected);
                                        }
                                    };
                                    runner = new $$AnimateRunner({
                                        end: function() {
                                            onAnimationComplete();
                                        },
                                        cancel: function() {
                                            onAnimationComplete(true);
                                        }
                                    });
                                    endProgressCb = executeAnimationFn(animation, element, event, options, function(result) {
                                        var cancelled = result === false;
                                        onAnimationComplete(cancelled);
                                    });
                                    return runner;
                                });
                            });
                            return operations;
                        }
    
                        function packageAnimations(element, event, options, animations, fnName) {
                            var operations = groupEventedAnimations(element, event, options, animations, fnName);
                            if (operations.length === 0) {
                                var a, b;
                                if (fnName === 'beforeSetClass') {
                                    a = groupEventedAnimations(element, 'removeClass', options, animations, 'beforeRemoveClass');
                                    b = groupEventedAnimations(element, 'addClass', options, animations, 'beforeAddClass');
                                } else if (fnName === 'setClass') {
                                    a = groupEventedAnimations(element, 'removeClass', options, animations, 'removeClass');
                                    b = groupEventedAnimations(element, 'addClass', options, animations, 'addClass');
                                }
                                if (a) {
                                    operations = operations.concat(a);
                                }
                                if (b) {
                                    operations = operations.concat(b);
                                }
                            }
                            if (operations.length === 0) return;
                            return function startAnimation(callback) {
                                var runners = [];
                                if (operations.length) {
                                    forEach(operations, function(animateFn) {
                                        runners.push(animateFn());
                                    });
                                }
                                runners.length ? $$AnimateRunner.all(runners, callback) : callback();
                                return function endFn(reject) {
                                    forEach(runners, function(runner) {
                                        reject ? runner.cancel() : runner.end();
                                    });
                                };
                            };
                        }
                    };
    
                    function lookupAnimations(classes) {
                        classes = isArray(classes) ? classes : classes.split(' ');
                        var matches = [],
                            flagMap = {};
                        for (var i = 0; i < classes.length; i++) {
                            var klass = classes[i],
                                animationFactory = $animateProvider.$$registeredAnimations[klass];
                            if (animationFactory && !flagMap[klass]) {
                                matches.push($injector.get(animationFactory));
                                flagMap[klass] = true;
                            }
                        }
                        return matches;
                    }
                }
            ];
        }];
        var $$AnimateJsDriverProvider = ['$$animationProvider', function($$animationProvider) {
            $$animationProvider.drivers.push('$$animateJsDriver');
            this.$get = ['$$animateJs', '$$AnimateRunner', function($$animateJs, $$AnimateRunner) {
                return function initDriverFn(animationDetails) {
                    if (animationDetails.from && animationDetails.to) {
                        var fromAnimation = prepareAnimation(animationDetails.from);
                        var toAnimation = prepareAnimation(animationDetails.to);
                        if (!fromAnimation && !toAnimation) return;
                        return {
                            start: function() {
                                var animationRunners = [];
                                if (fromAnimation) {
                                    animationRunners.push(fromAnimation.start());
                                }
                                if (toAnimation) {
                                    animationRunners.push(toAnimation.start());
                                }
                                $$AnimateRunner.all(animationRunners, done);
                                var runner = new $$AnimateRunner({
                                    end: endFnFactory(),
                                    cancel: endFnFactory()
                                });
                                return runner;
    
                                function endFnFactory() {
                                    return function() {
                                        forEach(animationRunners, function(runner) {
                                            runner.end();
                                        });
                                    };
                                }
    
                                function done(status) {
                                    runner.complete(status);
                                }
                            }
                        };
                    } else {
                        return prepareAnimation(animationDetails);
                    }
                };
    
                function prepareAnimation(animationDetails) {
                    var element = animationDetails.element;
                    var event = animationDetails.event;
                    var options = animationDetails.options;
                    var classes = animationDetails.classes;
                    return $$animateJs(element, event, classes, options);
                }
            }];
        }];
        var NG_ANIMATE_ATTR_NAME = 'data-ng-animate';
        var NG_ANIMATE_PIN_DATA = '$ngAnimatePin';
        var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
            var PRE_DIGEST_STATE = 1;
            var RUNNING_STATE = 2;
            var ONE_SPACE = ' ';
            var rules = this.rules = {
                skip: [],
                cancel: [],
                join: []
            };
    
            function makeTruthyCssClassMap(classString) {
                if (!classString) {
                    return null;
                }
                var keys = classString.split(ONE_SPACE);
                var map = Object.create(null);
                forEach(keys, function(key) {
                    map[key] = true;
                });
                return map;
            }
    
            function hasMatchingClasses(newClassString, currentClassString) {
                if (newClassString && currentClassString) {
                    var currentClassMap = makeTruthyCssClassMap(currentClassString);
                    return newClassString.split(ONE_SPACE).some(function(className) {
                        return currentClassMap[className];
                    });
                }
            }
    
            function isAllowed(ruleType, element, currentAnimation, previousAnimation) {
                return rules[ruleType].some(function(fn) {
                    return fn(element, currentAnimation, previousAnimation);
                });
            }
    
            function hasAnimationClasses(animation, and) {
                var a = (animation.addClass || '').length > 0;
                var b = (animation.removeClass || '').length > 0;
                return and ? a && b : a || b;
            }
            rules.join.push(function(element, newAnimation, currentAnimation) {
                return !newAnimation.structural && hasAnimationClasses(newAnimation);
            });
            rules.skip.push(function(element, newAnimation, currentAnimation) {
                return !newAnimation.structural && !hasAnimationClasses(newAnimation);
            });
            rules.skip.push(function(element, newAnimation, currentAnimation) {
                return currentAnimation.event == 'leave' && newAnimation.structural;
            });
            rules.skip.push(function(element, newAnimation, currentAnimation) {
                return currentAnimation.structural && currentAnimation.state === RUNNING_STATE && !newAnimation.structural;
            });
            rules.cancel.push(function(element, newAnimation, currentAnimation) {
                return currentAnimation.structural && newAnimation.structural;
            });
            rules.cancel.push(function(element, newAnimation, currentAnimation) {
                return currentAnimation.state === RUNNING_STATE && newAnimation.structural;
            });
            rules.cancel.push(function(element, newAnimation, currentAnimation) {
                if (currentAnimation.structural) return false;
                var nA = newAnimation.addClass;
                var nR = newAnimation.removeClass;
                var cA = currentAnimation.addClass;
                var cR = currentAnimation.removeClass;
                if ((isUndefined(nA) && isUndefined(nR)) || (isUndefined(cA) && isUndefined(cR))) {
                    return false;
                }
                return hasMatchingClasses(nA, cR) || hasMatchingClasses(nR, cA);
            });
            this.$get = ['$$rAF', '$rootScope', '$rootElement', '$document', '$$HashMap',
                '$$animation', '$$AnimateRunner', '$templateRequest', '$$jqLite', '$$forceReflow',
                function($$rAF, $rootScope, $rootElement, $document, $$HashMap,
                    $$animation, $$AnimateRunner, $templateRequest, $$jqLite, $$forceReflow) {
                    var activeAnimationsLookup = new $$HashMap();
                    var disabledElementsLookup = new $$HashMap();
                    var animationsEnabled = null;
    
                    function postDigestTaskFactory() {
                        var postDigestCalled = false;
                        return function(fn) {
                            if (postDigestCalled) {
                                fn();
                            } else {
                                $rootScope.$$postDigest(function() {
                                    postDigestCalled = true;
                                    fn();
                                });
                            }
                        };
                    }
                    var deregisterWatch = $rootScope.$watch(
                        function() {
                            return $templateRequest.totalPendingRequests === 0;
                        },
                        function(isEmpty) {
                            if (!isEmpty) return;
                            deregisterWatch();
                            $rootScope.$$postDigest(function() {
                                $rootScope.$$postDigest(function() {
                                    if (animationsEnabled === null) {
                                        animationsEnabled = true;
                                    }
                                });
                            });
                        }
                    );
                    var callbackRegistry = {};
                    var classNameFilter = $animateProvider.classNameFilter();
                    var isAnimatableClassName = !classNameFilter ?
                        function() {
                            return true;
                        } :
                        function(className) {
                            return classNameFilter.test(className);
                        };
                    var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
    
                    function normalizeAnimationDetails(element, animation) {
                        return mergeAnimationDetails(element, animation, {});
                    }
                    var contains = Node.prototype.contains || function(arg) {
                        return this === arg || !!(this.compareDocumentPosition(arg) & 16);
                    };
    
                    function findCallbacks(parent, element, event) {
                        var targetNode = getDomNode(element);
                        var targetParentNode = getDomNode(parent);
                        var matches = [];
                        var entries = callbackRegistry[event];
                        if (entries) {
                            forEach(entries, function(entry) {
                                if (contains.call(entry.node, targetNode)) {
                                    matches.push(entry.callback);
                                } else if (event === 'leave' && contains.call(entry.node, targetParentNode)) {
                                    matches.push(entry.callback);
                                }
                            });
                        }
                        return matches;
                    }
                    var $animate = {
                        on: function(event, container, callback) {
                            var node = extractElementNode(container);
                            callbackRegistry[event] = callbackRegistry[event] || [];
                            callbackRegistry[event].push({
                                node: node,
                                callback: callback
                            });
                            jqLite(container).on('$destroy', function() {
                                $animate.off(event, container, callback);
                            });
                        },
                        off: function(event, container, callback) {
                            var entries = callbackRegistry[event];
                            if (!entries) return;
                            callbackRegistry[event] = arguments.length === 1 ?
                                null :
                                filterFromRegistry(entries, container, callback);
    
                            function filterFromRegistry(list, matchContainer, matchCallback) {
                                var containerNode = extractElementNode(matchContainer);
                                return list.filter(function(entry) {
                                    var isMatch = entry.node === containerNode &&
                                        (!matchCallback || entry.callback === matchCallback);
                                    return !isMatch;
                                });
                            }
                        },
                        pin: function(element, parentElement) {
                            assertArg(isElement(element), 'element', 'not an element');
                            assertArg(isElement(parentElement), 'parentElement', 'not an element');
                            element.data(NG_ANIMATE_PIN_DATA, parentElement);
                        },
                        push: function(element, event, options, domOperation) {
                            options = options || {};
                            options.domOperation = domOperation;
                            return queueAnimation(element, event, options);
                        },
                        enabled: function(element, bool) {
                            var argCount = arguments.length;
                            if (argCount === 0) {
                                bool = !!animationsEnabled;
                            } else {
                                var hasElement = isElement(element);
                                if (!hasElement) {
                                    bool = animationsEnabled = !!element;
                                } else {
                                    var node = getDomNode(element);
                                    var recordExists = disabledElementsLookup.get(node);
                                    if (argCount === 1) {
                                        bool = !recordExists;
                                    } else {
                                        disabledElementsLookup.put(node, !bool);
                                    }
                                }
                            }
                            return bool;
                        }
                    };
                    return $animate;
    
                    function queueAnimation(element, event, initialOptions) {
                        var options = copy(initialOptions);
                        var node, parent;
                        element = stripCommentsFromElement(element);
                        if (element) {
                            node = getDomNode(element);
                            parent = element.parent();
                        }
                        options = prepareAnimationOptions(options);
                        var runner = new $$AnimateRunner();
                        var runInNextPostDigestOrNow = postDigestTaskFactory();
                        if (isArray(options.addClass)) {
                            options.addClass = options.addClass.join(' ');
                        }
                        if (options.addClass && !isString(options.addClass)) {
                            options.addClass = null;
                        }
                        if (isArray(options.removeClass)) {
                            options.removeClass = options.removeClass.join(' ');
                        }
                        if (options.removeClass && !isString(options.removeClass)) {
                            options.removeClass = null;
                        }
                        if (options.from && !isObject(options.from)) {
                            options.from = null;
                        }
                        if (options.to && !isObject(options.to)) {
                            options.to = null;
                        }
                        if (!node) {
                            close();
                            return runner;
                        }
                        var className = [node.className, options.addClass, options.removeClass].join(' ');
                        if (!isAnimatableClassName(className)) {
                            close();
                            return runner;
                        }
                        var isStructural = ['enter', 'move', 'leave'].indexOf(event) >= 0;
                        var skipAnimations = !animationsEnabled || $document[0].hidden || disabledElementsLookup.get(node);
                        var existingAnimation = (!skipAnimations && activeAnimationsLookup.get(node)) || {};
                        var hasExistingAnimation = !!existingAnimation.state;
                        if (!skipAnimations && (!hasExistingAnimation || existingAnimation.state != PRE_DIGEST_STATE)) {
                            skipAnimations = !areAnimationsAllowed(element, parent, event);
                        }
                        if (skipAnimations) {
                            close();
                            return runner;
                        }
                        if (isStructural) {
                            closeChildAnimations(element);
                        }
                        var newAnimation = {
                            structural: isStructural,
                            element: element,
                            event: event,
                            addClass: options.addClass,
                            removeClass: options.removeClass,
                            close: close,
                            options: options,
                            runner: runner
                        };
                        if (hasExistingAnimation) {
                            var skipAnimationFlag = isAllowed('skip', element, newAnimation, existingAnimation);
                            if (skipAnimationFlag) {
                                if (existingAnimation.state === RUNNING_STATE) {
                                    close();
                                    return runner;
                                } else {
                                    mergeAnimationDetails(element, existingAnimation, newAnimation);
                                    return existingAnimation.runner;
                                }
                            }
                            var cancelAnimationFlag = isAllowed('cancel', element, newAnimation, existingAnimation);
                            if (cancelAnimationFlag) {
                                if (existingAnimation.state === RUNNING_STATE) {
                                    existingAnimation.runner.end();
                                } else if (existingAnimation.structural) {
                                    existingAnimation.close();
                                } else {
                                    mergeAnimationDetails(element, existingAnimation, newAnimation);
                                    return existingAnimation.runner;
                                }
                            } else {
                                var joinAnimationFlag = isAllowed('join', element, newAnimation, existingAnimation);
                                if (joinAnimationFlag) {
                                    if (existingAnimation.state === RUNNING_STATE) {
                                        normalizeAnimationDetails(element, newAnimation);
                                    } else {
                                        applyGeneratedPreparationClasses(element, isStructural ? event : null, options);
                                        event = newAnimation.event = existingAnimation.event;
                                        options = mergeAnimationDetails(element, existingAnimation, newAnimation);
                                        return existingAnimation.runner;
                                    }
                                }
                            }
                        } else {
                            normalizeAnimationDetails(element, newAnimation);
                        }
                        var isValidAnimation = newAnimation.structural;
                        if (!isValidAnimation) {
                            isValidAnimation = (newAnimation.event === 'animate' && Object.keys(newAnimation.options.to || {}).length > 0) ||
                                hasAnimationClasses(newAnimation);
                        }
                        if (!isValidAnimation) {
                            close();
                            clearElementAnimationState(element);
                            return runner;
                        }
                        var counter = (existingAnimation.counter || 0) + 1;
                        newAnimation.counter = counter;
                        markElementAnimationState(element, PRE_DIGEST_STATE, newAnimation);
                        $rootScope.$$postDigest(function() {
                            var animationDetails = activeAnimationsLookup.get(node);
                            var animationCancelled = !animationDetails;
                            animationDetails = animationDetails || {};
                            var parentElement = element.parent() || [];
                            var isValidAnimation = parentElement.length > 0 &&
                                (animationDetails.event === 'animate' ||
                                    animationDetails.structural ||
                                    hasAnimationClasses(animationDetails));
                            if (animationCancelled || animationDetails.counter !== counter || !isValidAnimation) {
                                if (animationCancelled) {
                                    applyAnimationClasses(element, options);
                                    applyAnimationStyles(element, options);
                                }
                                if (animationCancelled || (isStructural && animationDetails.event !== event)) {
                                    options.domOperation();
                                    runner.end();
                                }
                                if (!isValidAnimation) {
                                    clearElementAnimationState(element);
                                }
                                return;
                            }
                            event = !animationDetails.structural && hasAnimationClasses(animationDetails, true) ?
                                'setClass' :
                                animationDetails.event;
                            markElementAnimationState(element, RUNNING_STATE);
                            var realRunner = $$animation(element, event, animationDetails.options);
                            realRunner.done(function(status) {
                                close(!status);
                                var animationDetails = activeAnimationsLookup.get(node);
                                if (animationDetails && animationDetails.counter === counter) {
                                    clearElementAnimationState(getDomNode(element));
                                }
                                notifyProgress(runner, event, 'close', {});
                            });
                            runner.setHost(realRunner);
                            notifyProgress(runner, event, 'start', {});
                        });
                        return runner;
    
                        function notifyProgress(runner, event, phase, data) {
                            runInNextPostDigestOrNow(function() {
                                var callbacks = findCallbacks(parent, element, event);
                                if (callbacks.length) {
                                    $$rAF(function() {
                                        forEach(callbacks, function(callback) {
                                            callback(element, phase, data);
                                        });
                                    });
                                }
                            });
                            runner.progress(event, phase, data);
                        }
    
                        function close(reject) {
                            clearGeneratedClasses(element, options);
                            applyAnimationClasses(element, options);
                            applyAnimationStyles(element, options);
                            options.domOperation();
                            runner.complete(!reject);
                        }
                    }
    
                    function closeChildAnimations(element) {
                        var node = getDomNode(element);
                        var children = node.querySelectorAll('[' + NG_ANIMATE_ATTR_NAME + ']');
                        forEach(children, function(child) {
                            var state = parseInt(child.getAttribute(NG_ANIMATE_ATTR_NAME));
                            var animationDetails = activeAnimationsLookup.get(child);
                            if (animationDetails) {
                                switch (state) {
                                    case RUNNING_STATE:
                                        animationDetails.runner.end();
                                    case PRE_DIGEST_STATE:
                                        activeAnimationsLookup.remove(child);
                                        break;
                                }
                            }
                        });
                    }
    
                    function clearElementAnimationState(element) {
                        var node = getDomNode(element);
                        node.removeAttribute(NG_ANIMATE_ATTR_NAME);
                        activeAnimationsLookup.remove(node);
                    }
    
                    function isMatchingElement(nodeOrElmA, nodeOrElmB) {
                        return getDomNode(nodeOrElmA) === getDomNode(nodeOrElmB);
                    }
    
                    function areAnimationsAllowed(element, parentElement, event) {
                        var bodyElement = jqLite($document[0].body);
                        var bodyElementDetected = isMatchingElement(element, bodyElement) || element[0].nodeName === 'HTML';
                        var rootElementDetected = isMatchingElement(element, $rootElement);
                        var parentAnimationDetected = false;
                        var animateChildren;
                        var elementDisabled = disabledElementsLookup.get(getDomNode(element));
                        var parentHost = jqLite.data(element[0], NG_ANIMATE_PIN_DATA);
                        if (parentHost) {
                            parentElement = parentHost;
                        }
                        parentElement = getDomNode(parentElement);
                        while (parentElement) {
                            if (!rootElementDetected) {
                                rootElementDetected = isMatchingElement(parentElement, $rootElement);
                            }
                            if (parentElement.nodeType !== ELEMENT_NODE) {
                                break;
                            }
                            var details = activeAnimationsLookup.get(parentElement) || {};
                            if (!parentAnimationDetected) {
                                var parentElementDisabled = disabledElementsLookup.get(parentElement);
                                if (parentElementDisabled === true && elementDisabled !== false) {
                                    elementDisabled = true;
                                    break;
                                } else if (parentElementDisabled === false) {
                                    elementDisabled = false;
                                }
                                parentAnimationDetected = details.structural;
                            }
                            if (isUndefined(animateChildren) || animateChildren === true) {
                                var value = jqLite.data(parentElement, NG_ANIMATE_CHILDREN_DATA);
                                if (isDefined(value)) {
                                    animateChildren = value;
                                }
                            }
                            if (parentAnimationDetected && animateChildren === false) break;
                            if (!bodyElementDetected) {
                                bodyElementDetected = isMatchingElement(parentElement, bodyElement);
                            }
                            if (bodyElementDetected && rootElementDetected) {
                                break;
                            }
                            if (!rootElementDetected) {
                                parentHost = jqLite.data(parentElement, NG_ANIMATE_PIN_DATA);
                                if (parentHost) {
                                    parentElement = getDomNode(parentHost);
                                    continue;
                                }
                            }
                            parentElement = parentElement.parentNode;
                        }
                        var allowAnimation = (!parentAnimationDetected || animateChildren) && elementDisabled !== true;
                        return allowAnimation && rootElementDetected && bodyElementDetected;
                    }
    
                    function markElementAnimationState(element, state, details) {
                        details = details || {};
                        details.state = state;
                        var node = getDomNode(element);
                        node.setAttribute(NG_ANIMATE_ATTR_NAME, state);
                        var oldValue = activeAnimationsLookup.get(node);
                        var newValue = oldValue ?
                            extend(oldValue, details) :
                            details;
                        activeAnimationsLookup.put(node, newValue);
                    }
                }
            ];
        }];
        var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
            var NG_ANIMATE_REF_ATTR = 'ng-animate-ref';
            var drivers = this.drivers = [];
            var RUNNER_STORAGE_KEY = '$$animationRunner';
    
            function setRunner(element, runner) {
                element.data(RUNNER_STORAGE_KEY, runner);
            }
    
            function removeRunner(element) {
                element.removeData(RUNNER_STORAGE_KEY);
            }
    
            function getRunner(element) {
                return element.data(RUNNER_STORAGE_KEY);
            }
            this.$get = ['$$jqLite', '$rootScope', '$injector', '$$AnimateRunner', '$$HashMap', '$$rAFScheduler',
                function($$jqLite, $rootScope, $injector, $$AnimateRunner, $$HashMap, $$rAFScheduler) {
                    var animationQueue = [];
                    var applyAnimationClasses = applyAnimationClassesFactory($$jqLite);
    
                    function sortAnimations(animations) {
                        var tree = {
                            children: []
                        };
                        var i, lookup = new $$HashMap();
                        for (i = 0; i < animations.length; i++) {
                            var animation = animations[i];
                            lookup.put(animation.domNode, animations[i] = {
                                domNode: animation.domNode,
                                fn: animation.fn,
                                children: []
                            });
                        }
                        for (i = 0; i < animations.length; i++) {
                            processNode(animations[i]);
                        }
                        return flatten(tree);
    
                        function processNode(entry) {
                            if (entry.processed) return entry;
                            entry.processed = true;
                            var elementNode = entry.domNode;
                            var parentNode = elementNode.parentNode;
                            lookup.put(elementNode, entry);
                            var parentEntry;
                            while (parentNode) {
                                parentEntry = lookup.get(parentNode);
                                if (parentEntry) {
                                    if (!parentEntry.processed) {
                                        parentEntry = processNode(parentEntry);
                                    }
                                    break;
                                }
                                parentNode = parentNode.parentNode;
                            }
                            (parentEntry || tree).children.push(entry);
                            return entry;
                        }
    
                        function flatten(tree) {
                            var result = [];
                            var queue = [];
                            var i;
                            for (i = 0; i < tree.children.length; i++) {
                                queue.push(tree.children[i]);
                            }
                            var remainingLevelEntries = queue.length;
                            var nextLevelEntries = 0;
                            var row = [];
                            for (i = 0; i < queue.length; i++) {
                                var entry = queue[i];
                                if (remainingLevelEntries <= 0) {
                                    remainingLevelEntries = nextLevelEntries;
                                    nextLevelEntries = 0;
                                    result.push(row);
                                    row = [];
                                }
                                row.push(entry.fn);
                                entry.children.forEach(function(childEntry) {
                                    nextLevelEntries++;
                                    queue.push(childEntry);
                                });
                                remainingLevelEntries--;
                            }
                            if (row.length) {
                                result.push(row);
                            }
                            return result;
                        }
                    }
                    return function(element, event, options) {
                        options = prepareAnimationOptions(options);
                        var isStructural = ['enter', 'move', 'leave'].indexOf(event) >= 0;
                        var runner = new $$AnimateRunner({
                            end: function() {
                                close();
                            },
                            cancel: function() {
                                close(true);
                            }
                        });
                        if (!drivers.length) {
                            close();
                            return runner;
                        }
                        setRunner(element, runner);
                        var classes = mergeClasses(element.attr('class'), mergeClasses(options.addClass, options.removeClass));
                        var tempClasses = options.tempClasses;
                        if (tempClasses) {
                            classes += ' ' + tempClasses;
                            options.tempClasses = null;
                        }
                        var prepareClassName;
                        if (isStructural) {
                            prepareClassName = 'ng-' + event + PREPARE_CLASS_SUFFIX;
                            $$jqLite.addClass(element, prepareClassName);
                        }
                        animationQueue.push({
                            element: element,
                            classes: classes,
                            event: event,
                            structural: isStructural,
                            options: options,
                            beforeStart: beforeStart,
                            close: close
                        });
                        element.on('$destroy', handleDestroyedElement);
                        if (animationQueue.length > 1) return runner;
                        $rootScope.$$postDigest(function() {
                            var animations = [];
                            forEach(animationQueue, function(entry) {
                                if (getRunner(entry.element)) {
                                    animations.push(entry);
                                } else {
                                    entry.close();
                                }
                            });
                            animationQueue.length = 0;
                            var groupedAnimations = groupAnimations(animations);
                            var toBeSortedAnimations = [];
                            forEach(groupedAnimations, function(animationEntry) {
                                toBeSortedAnimations.push({
                                    domNode: getDomNode(animationEntry.from ? animationEntry.from.element : animationEntry.element),
                                    fn: function triggerAnimationStart() {
                                        animationEntry.beforeStart();
                                        var startAnimationFn, closeFn = animationEntry.close;
                                        var targetElement = animationEntry.anchors ?
                                            (animationEntry.from.element || animationEntry.to.element) :
                                            animationEntry.element;
                                        if (getRunner(targetElement)) {
                                            var operation = invokeFirstDriver(animationEntry);
                                            if (operation) {
                                                startAnimationFn = operation.start;
                                            }
                                        }
                                        if (!startAnimationFn) {
                                            closeFn();
                                        } else {
                                            var animationRunner = startAnimationFn();
                                            animationRunner.done(function(status) {
                                                closeFn(!status);
                                            });
                                            updateAnimationRunners(animationEntry, animationRunner);
                                        }
                                    }
                                });
                            });
                            $$rAFScheduler(sortAnimations(toBeSortedAnimations));
                        });
                        return runner;
    
                        function getAnchorNodes(node) {
                            var SELECTOR = '[' + NG_ANIMATE_REF_ATTR + ']';
                            var items = node.hasAttribute(NG_ANIMATE_REF_ATTR) ?
                                [node] :
                                node.querySelectorAll(SELECTOR);
                            var anchors = [];
                            forEach(items, function(node) {
                                var attr = node.getAttribute(NG_ANIMATE_REF_ATTR);
                                if (attr && attr.length) {
                                    anchors.push(node);
                                }
                            });
                            return anchors;
                        }
    
                        function groupAnimations(animations) {
                            var preparedAnimations = [];
                            var refLookup = {};
                            forEach(animations, function(animation, index) {
                                var element = animation.element;
                                var node = getDomNode(element);
                                var event = animation.event;
                                var enterOrMove = ['enter', 'move'].indexOf(event) >= 0;
                                var anchorNodes = animation.structural ? getAnchorNodes(node) : [];
                                if (anchorNodes.length) {
                                    var direction = enterOrMove ? 'to' : 'from';
                                    forEach(anchorNodes, function(anchor) {
                                        var key = anchor.getAttribute(NG_ANIMATE_REF_ATTR);
                                        refLookup[key] = refLookup[key] || {};
                                        refLookup[key][direction] = {
                                            animationID: index,
                                            element: jqLite(anchor)
                                        };
                                    });
                                } else {
                                    preparedAnimations.push(animation);
                                }
                            });
                            var usedIndicesLookup = {};
                            var anchorGroups = {};
                            forEach(refLookup, function(operations, key) {
                                var from = operations.from;
                                var to = operations.to;
                                if (!from || !to) {
                                    var index = from ? from.animationID : to.animationID;
                                    var indexKey = index.toString();
                                    if (!usedIndicesLookup[indexKey]) {
                                        usedIndicesLookup[indexKey] = true;
                                        preparedAnimations.push(animations[index]);
                                    }
                                    return;
                                }
                                var fromAnimation = animations[from.animationID];
                                var toAnimation = animations[to.animationID];
                                var lookupKey = from.animationID.toString();
                                if (!anchorGroups[lookupKey]) {
                                    var group = anchorGroups[lookupKey] = {
                                        structural: true,
                                        beforeStart: function() {
                                            fromAnimation.beforeStart();
                                            toAnimation.beforeStart();
                                        },
                                        close: function() {
                                            fromAnimation.close();
                                            toAnimation.close();
                                        },
                                        classes: cssClassesIntersection(fromAnimation.classes, toAnimation.classes),
                                        from: fromAnimation,
                                        to: toAnimation,
                                        anchors: []
                                    };
                                    if (group.classes.length) {
                                        preparedAnimations.push(group);
                                    } else {
                                        preparedAnimations.push(fromAnimation);
                                        preparedAnimations.push(toAnimation);
                                    }
                                }
                                anchorGroups[lookupKey].anchors.push({
                                    'out': from.element,
                                    'in': to.element
                                });
                            });
                            return preparedAnimations;
                        }
    
                        function cssClassesIntersection(a, b) {
                            a = a.split(' ');
                            b = b.split(' ');
                            var matches = [];
                            for (var i = 0; i < a.length; i++) {
                                var aa = a[i];
                                if (aa.substring(0, 3) === 'ng-') continue;
                                for (var j = 0; j < b.length; j++) {
                                    if (aa === b[j]) {
                                        matches.push(aa);
                                        break;
                                    }
                                }
                            }
                            return matches.join(' ');
                        }
    
                        function invokeFirstDriver(animationDetails) {
                            for (var i = drivers.length - 1; i >= 0; i--) {
                                var driverName = drivers[i];
                                if (!$injector.has(driverName)) continue;
                                var factory = $injector.get(driverName);
                                var driver = factory(animationDetails);
                                if (driver) {
                                    return driver;
                                }
                            }
                        }
    
                        function beforeStart() {
                            element.addClass(NG_ANIMATE_CLASSNAME);
                            if (tempClasses) {
                                $$jqLite.addClass(element, tempClasses);
                            }
                            if (prepareClassName) {
                                $$jqLite.removeClass(element, prepareClassName);
                                prepareClassName = null;
                            }
                        }
    
                        function updateAnimationRunners(animation, newRunner) {
                            if (animation.from && animation.to) {
                                update(animation.from.element);
                                update(animation.to.element);
                            } else {
                                update(animation.element);
                            }
    
                            function update(element) {
                                getRunner(element).setHost(newRunner);
                            }
                        }
    
                        function handleDestroyedElement() {
                            var runner = getRunner(element);
                            if (runner && (event !== 'leave' || !options.$$domOperationFired)) {
                                runner.end();
                            }
                        }
    
                        function close(rejected) {
                            element.off('$destroy', handleDestroyedElement);
                            removeRunner(element);
                            applyAnimationClasses(element, options);
                            applyAnimationStyles(element, options);
                            options.domOperation();
                            if (tempClasses) {
                                $$jqLite.removeClass(element, tempClasses);
                            }
                            element.removeClass(NG_ANIMATE_CLASSNAME);
                            runner.complete(!rejected);
                        }
                    };
                }
            ];
        }];
        var ngAnimateSwapDirective = ['$animate', '$rootScope', function($animate, $rootScope) {
            return {
                restrict: 'A',
                transclude: 'element',
                terminal: true,
                priority: 600,
                link: function(scope, $element, attrs, ctrl, $transclude) {
                    var previousElement, previousScope;
                    scope.$watchCollection(attrs.ngAnimateSwap || attrs['for'], function(value) {
                        if (previousElement) {
                            $animate.leave(previousElement);
                        }
                        if (previousScope) {
                            previousScope.$destroy();
                            previousScope = null;
                        }
                        if (value || value === 0) {
                            previousScope = scope.$new();
                            $transclude(previousScope, function(element) {
                                previousElement = element;
                                $animate.enter(element, null, $element);
                            });
                        }
                    });
                }
            };
        }];
        angular.module('ngAnimate', [])
            .directive('ngAnimateSwap', ngAnimateSwapDirective)
            .directive('ngAnimateChildren', $$AnimateChildrenDirective)
            .factory('$$rAFScheduler', $$rAFSchedulerFactory)
            .provider('$$animateQueue', $$AnimateQueueProvider)
            .provider('$$animation', $$AnimationProvider)
            .provider('$animateCss', $AnimateCssProvider)
            .provider('$$animateCssDriver', $$AnimateCssDriverProvider)
            .provider('$$animateJs', $$AnimateJsProvider)
            .provider('$$animateJsDriver', $$AnimateJsDriverProvider);
    })(window, window.angular);;
    /*! RESOURCE: /scripts/angular_1.5.3/angular-resource.js */
    (function(window, angular, undefined) {
        'use strict';
        var $resourceMinErr = angular.$$minErr('$resource');
        var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;
    
        function isValidDottedPath(path) {
            return (path != null && path !== '' && path !== 'hasOwnProperty' &&
                MEMBER_NAME_REGEX.test('.' + path));
        }
    
        function lookupDottedPath(obj, path) {
            if (!isValidDottedPath(path)) {
                throw $resourceMinErr('badmember', 'Dotted member path "@{0}" is invalid.', path);
            }
            var keys = path.split('.');
            for (var i = 0, ii = keys.length; i < ii && angular.isDefined(obj); i++) {
                var key = keys[i];
                obj = (obj !== null) ? obj[key] : undefined;
            }
            return obj;
        }
    
        function shallowClearAndCopy(src, dst) {
            dst = dst || {};
            angular.forEach(dst, function(value, key) {
                delete dst[key];
            });
            for (var key in src) {
                if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
                    dst[key] = src[key];
                }
            }
            return dst;
        }
        angular.module('ngResource', ['ng']).
        provider('$resource', function() {
            var PROTOCOL_AND_DOMAIN_REGEX = /^https?:\/\/[^\/]*/;
            var provider = this;
            this.defaults = {
                stripTrailingSlashes: true,
                actions: {
                    'get': {
                        method: 'GET'
                    },
                    'save': {
                        method: 'POST'
                    },
                    'query': {
                        method: 'GET',
                        isArray: true
                    },
                    'remove': {
                        method: 'DELETE'
                    },
                    'delete': {
                        method: 'DELETE'
                    }
                }
            };
            this.$get = ['$http', '$log', '$q', '$timeout', function($http, $log, $q, $timeout) {
                var noop = angular.noop,
                    forEach = angular.forEach,
                    extend = angular.extend,
                    copy = angular.copy,
                    isFunction = angular.isFunction;
    
                function encodeUriSegment(val) {
                    return encodeUriQuery(val, true).
                    replace(/%26/gi, '&').
                    replace(/%3D/gi, '=').
                    replace(/%2B/gi, '+');
                }
    
                function encodeUriQuery(val, pctEncodeSpaces) {
                    return encodeURIComponent(val).
                    replace(/%40/gi, '@').
                    replace(/%3A/gi, ':').
                    replace(/%24/g, '$').
                    replace(/%2C/gi, ',').
                    replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
                }
    
                function Route(template, defaults) {
                    this.template = template;
                    this.defaults = extend({}, provider.defaults, defaults);
                    this.urlParams = {};
                }
                Route.prototype = {
                    setUrlParams: function(config, params, actionUrl) {
                        var self = this,
                            url = actionUrl || self.template,
                            val,
                            encodedVal,
                            protocolAndDomain = '';
                        var urlParams = self.urlParams = {};
                        forEach(url.split(/\W/), function(param) {
                            if (param === 'hasOwnProperty') {
                                throw $resourceMinErr('badname', "hasOwnProperty is not a valid parameter name.");
                            }
                            if (!(new RegExp("^\\d+$").test(param)) && param &&
                                (new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) {
                                urlParams[param] = {
                                    isQueryParamValue: (new RegExp("\\?.*=:" + param + "(?:\\W|$)")).test(url)
                                };
                            }
                        });
                        url = url.replace(/\\:/g, ':');
                        url = url.replace(PROTOCOL_AND_DOMAIN_REGEX, function(match) {
                            protocolAndDomain = match;
                            return '';
                        });
                        params = params || {};
                        forEach(self.urlParams, function(paramInfo, urlParam) {
                            val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];
                            if (angular.isDefined(val) && val !== null) {
                                if (paramInfo.isQueryParamValue) {
                                    encodedVal = encodeUriQuery(val, true);
                                } else {
                                    encodedVal = encodeUriSegment(val);
                                }
                                url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), function(match, p1) {
                                    return encodedVal + p1;
                                });
                            } else {
                                url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match,
                                    leadingSlashes, tail) {
                                    if (tail.charAt(0) == '/') {
                                        return tail;
                                    } else {
                                        return leadingSlashes + tail;
                                    }
                                });
                            }
                        });
                        if (self.defaults.stripTrailingSlashes) {
                            url = url.replace(/\/+$/, '') || '/';
                        }
                        url = url.replace(/\/\.(?=\w+($|\?))/, '.');
                        config.url = protocolAndDomain + url.replace(/\/\\\./, '/.');
                        forEach(params, function(value, key) {
                            if (!self.urlParams[key]) {
                                config.params = config.params || {};
                                config.params[key] = value;
                            }
                        });
                    }
                };
    
                function resourceFactory(url, paramDefaults, actions, options) {
                    var route = new Route(url, options);
                    actions = extend({}, provider.defaults.actions, actions);
    
                    function extractParams(data, actionParams) {
                        var ids = {};
                        actionParams = extend({}, paramDefaults, actionParams);
                        forEach(actionParams, function(value, key) {
                            if (isFunction(value)) {
                                value = value();
                            }
                            ids[key] = value && value.charAt && value.charAt(0) == '@' ?
                                lookupDottedPath(data, value.substr(1)) : value;
                        });
                        return ids;
                    }
    
                    function defaultResponseInterceptor(response) {
                        return response.resource;
                    }
    
                    function Resource(value) {
                        shallowClearAndCopy(value || {}, this);
                    }
                    Resource.prototype.toJSON = function() {
                        var data = extend({}, this);
                        delete data.$promise;
                        delete data.$resolved;
                        return data;
                    };
                    forEach(actions, function(action, name) {
                        var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method);
                        var numericTimeout = action.timeout;
                        var cancellable = angular.isDefined(action.cancellable) ? action.cancellable :
                            (options && angular.isDefined(options.cancellable)) ? options.cancellable :
                            provider.defaults.cancellable;
                        if (numericTimeout && !angular.isNumber(numericTimeout)) {
                            $log.debug('ngResource:\n' +
                                '  Only numeric values are allowed as `timeout`.\n' +
                                '  Promises are not supported in $resource, because the same value would ' +
                                'be used for multiple requests. If you are looking for a way to cancel ' +
                                'requests, you should use the `cancellable` option.');
                            delete action.timeout;
                            numericTimeout = null;
                        }
                        Resource[name] = function(a1, a2, a3, a4) {
                            var params = {},
                                data, success, error;
                            switch (arguments.length) {
                                case 4:
                                    error = a4;
                                    success = a3;
                                case 3:
                                case 2:
                                    if (isFunction(a2)) {
                                        if (isFunction(a1)) {
                                            success = a1;
                                            error = a2;
                                            break;
                                        }
                                        success = a2;
                                        error = a3;
                                    } else {
                                        params = a1;
                                        data = a2;
                                        success = a3;
                                        break;
                                    }
                                case 1:
                                    if (isFunction(a1)) success = a1;
                                    else if (hasBody) data = a1;
                                    else params = a1;
                                    break;
                                case 0:
                                    break;
                                default:
                                    throw $resourceMinErr('badargs',
                                        "Expected up to 4 arguments [params, data, success, error], got {0} arguments",
                                        arguments.length);
                            }
                            var isInstanceCall = this instanceof Resource;
                            var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data));
                            var httpConfig = {};
                            var responseInterceptor = action.interceptor && action.interceptor.response ||
                                defaultResponseInterceptor;
                            var responseErrorInterceptor = action.interceptor && action.interceptor.responseError ||
                                undefined;
                            var timeoutDeferred;
                            var numericTimeoutPromise;
                            forEach(action, function(value, key) {
                                switch (key) {
                                    default: httpConfig[key] = copy(value);
                                    break;
                                    case 'params':
                                            case 'isArray':
                                            case 'interceptor':
                                            case 'cancellable':
                                            break;
                                }
                            });
                            if (!isInstanceCall && cancellable) {
                                timeoutDeferred = $q.defer();
                                httpConfig.timeout = timeoutDeferred.promise;
                                if (numericTimeout) {
                                    numericTimeoutPromise = $timeout(timeoutDeferred.resolve, numericTimeout);
                                }
                            }
                            if (hasBody) httpConfig.data = data;
                            route.setUrlParams(httpConfig,
                                extend({}, extractParams(data, action.params || {}), params),
                                action.url);
                            var promise = $http(httpConfig).then(function(response) {
                                var data = response.data;
                                if (data) {
                                    if (angular.isArray(data) !== (!!action.isArray)) {
                                        throw $resourceMinErr('badcfg',
                                            'Error in resource configuration for action `{0}`. Expected response to ' +
                                            'contain an {1} but got an {2} (Request: {3} {4})', name, action.isArray ? 'array' : 'object',
                                            angular.isArray(data) ? 'array' : 'object', httpConfig.method, httpConfig.url);
                                    }
                                    if (action.isArray) {
                                        value.length = 0;
                                        forEach(data, function(item) {
                                            if (typeof item === "object") {
                                                value.push(new Resource(item));
                                            } else {
                                                value.push(item);
                                            }
                                        });
                                    } else {
                                        var promise = value.$promise;
                                        shallowClearAndCopy(data, value);
                                        value.$promise = promise;
                                    }
                                }
                                response.resource = value;
                                return response;
                            }, function(response) {
                                (error || noop)(response);
                                return $q.reject(response);
                            });
                            promise['finally'](function() {
                                value.$resolved = true;
                                if (!isInstanceCall && cancellable) {
                                    value.$cancelRequest = angular.noop;
                                    $timeout.cancel(numericTimeoutPromise);
                                    timeoutDeferred = numericTimeoutPromise = httpConfig.timeout = null;
                                }
                            });
                            promise = promise.then(
                                function(response) {
                                    var value = responseInterceptor(response);
                                    (success || noop)(value, response.headers);
                                    return value;
                                },
                                responseErrorInterceptor);
                            if (!isInstanceCall) {
                                value.$promise = promise;
                                value.$resolved = false;
                                if (cancellable) value.$cancelRequest = timeoutDeferred.resolve;
                                return value;
                            }
                            return promise;
                        };
                        Resource.prototype['$' + name] = function(params, success, error) {
                            if (isFunction(params)) {
                                error = success;
                                success = params;
                                params = {};
                            }
                            var result = Resource[name].call(this, params, this, success, error);
                            return result.$promise || result;
                        };
                    });
                    Resource.bind = function(additionalParamDefaults) {
                        return resourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions);
                    };
                    return Resource;
                }
                return resourceFactory;
            }];
        });
    })(window, window.angular);;
    /*! RESOURCE: /scripts/angular_1.5.3/angular-route.js */
    (function(window, angular, undefined) {
        'use strict';
        var ngRouteModule = angular.module('ngRoute', ['ng']).
        provider('$route', $RouteProvider).
        run(['$route', angular.noop]),
            $routeMinErr = angular.$$minErr('ngRoute');
    
        function $RouteProvider() {
            function inherit(parent, extra) {
                return angular.extend(Object.create(parent), extra);
            }
            var routes = {};
            this.when = function(path, route) {
                var routeCopy = angular.copy(route);
                if (angular.isUndefined(routeCopy.reloadOnSearch)) {
                    routeCopy.reloadOnSearch = true;
                }
                if (angular.isUndefined(routeCopy.caseInsensitiveMatch)) {
                    routeCopy.caseInsensitiveMatch = this.caseInsensitiveMatch;
                }
                routes[path] = angular.extend(
                    routeCopy,
                    path && pathRegExp(path, routeCopy)
                );
                if (path) {
                    var redirectPath = (path[path.length - 1] == '/') ?
                        path.substr(0, path.length - 1) :
                        path + '/';
                    routes[redirectPath] = angular.extend({
                            redirectTo: path
                        },
                        pathRegExp(redirectPath, routeCopy)
                    );
                }
                return this;
            };
            this.caseInsensitiveMatch = false;
    
            function pathRegExp(path, opts) {
                var insensitive = opts.caseInsensitiveMatch,
                    ret = {
                        originalPath: path,
                        regexp: path
                    },
                    keys = ret.keys = [];
                path = path
                    .replace(/([().])/g, '\\$1')
                    .replace(/(\/)?:(\w+)(\*\?|[\?\*])?/g, function(_, slash, key, option) {
                        var optional = (option === '?' || option === '*?') ? '?' : null;
                        var star = (option === '*' || option === '*?') ? '*' : null;
                        keys.push({
                            name: key,
                            optional: !!optional
                        });
                        slash = slash || '';
                        return '' +
                            (optional ? '' : slash) +
                            '(?:' +
                            (optional ? slash : '') +
                            (star && '(.+?)' || '([^/]+)') +
                            (optional || '') +
                            ')' +
                            (optional || '');
                    })
                    .replace(/([\/$\*])/g, '\\$1');
                ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : '');
                return ret;
            }
            this.otherwise = function(params) {
                if (typeof params === 'string') {
                    params = {
                        redirectTo: params
                    };
                }
                this.when(null, params);
                return this;
            };
            this.$get = ['$rootScope',
                '$location',
                '$routeParams',
                '$q',
                '$injector',
                '$templateRequest',
                '$sce',
                function($rootScope, $location, $routeParams, $q, $injector, $templateRequest, $sce) {
                    var forceReload = false,
                        preparedRoute,
                        preparedRouteIsUpdateOnly,
                        $route = {
                            routes: routes,
                            reload: function() {
                                forceReload = true;
                                var fakeLocationEvent = {
                                    defaultPrevented: false,
                                    preventDefault: function fakePreventDefault() {
                                        this.defaultPrevented = true;
                                        forceReload = false;
                                    }
                                };
                                $rootScope.$evalAsync(function() {
                                    prepareRoute(fakeLocationEvent);
                                    if (!fakeLocationEvent.defaultPrevented) commitRoute();
                                });
                            },
                            updateParams: function(newParams) {
                                if (this.current && this.current.$$route) {
                                    newParams = angular.extend({}, this.current.params, newParams);
                                    $location.path(interpolate(this.current.$$route.originalPath, newParams));
                                    $location.search(newParams);
                                } else {
                                    throw $routeMinErr('norout', 'Tried updating route when with no current route');
                                }
                            }
                        };
                    $rootScope.$on('$locationChangeStart', prepareRoute);
                    $rootScope.$on('$locationChangeSuccess', commitRoute);
                    return $route;
    
                    function switchRouteMatcher(on, route) {
                        var keys = route.keys,
                            params = {};
                        if (!route.regexp) return null;
                        var m = route.regexp.exec(on);
                        if (!m) return null;
                        for (var i = 1, len = m.length; i < len; ++i) {
                            var key = keys[i - 1];
                            var val = m[i];
                            if (key && val) {
                                params[key.name] = val;
                            }
                        }
                        return params;
                    }
    
                    function prepareRoute($locationEvent) {
                        var lastRoute = $route.current;
                        preparedRoute = parseRoute();
                        preparedRouteIsUpdateOnly = preparedRoute && lastRoute && preparedRoute.$$route === lastRoute.$$route &&
                            angular.equals(preparedRoute.pathParams, lastRoute.pathParams) &&
                            !preparedRoute.reloadOnSearch && !forceReload;
                        if (!preparedRouteIsUpdateOnly && (lastRoute || preparedRoute)) {
                            if ($rootScope.$broadcast('$routeChangeStart', preparedRoute, lastRoute).defaultPrevented) {
                                if ($locationEvent) {
                                    $locationEvent.preventDefault();
                                }
                            }
                        }
                    }
    
                    function commitRoute() {
                        var lastRoute = $route.current;
                        var nextRoute = preparedRoute;
                        if (preparedRouteIsUpdateOnly) {
                            lastRoute.params = nextRoute.params;
                            angular.copy(lastRoute.params, $routeParams);
                            $rootScope.$broadcast('$routeUpdate', lastRoute);
                        } else if (nextRoute || lastRoute) {
                            forceReload = false;
                            $route.current = nextRoute;
                            if (nextRoute) {
                                if (nextRoute.redirectTo) {
                                    if (angular.isString(nextRoute.redirectTo)) {
                                        $location.path(interpolate(nextRoute.redirectTo, nextRoute.params)).search(nextRoute.params)
                                            .replace();
                                    } else {
                                        $location.url(nextRoute.redirectTo(nextRoute.pathParams, $location.path(), $location.search()))
                                            .replace();
                                    }
                                }
                            }
                            $q.when(nextRoute).
                            then(function() {
                                if (nextRoute) {
                                    var locals = angular.extend({}, nextRoute.resolve),
                                        template, templateUrl;
                                    angular.forEach(locals, function(value, key) {
                                        locals[key] = angular.isString(value) ?
                                            $injector.get(value) : $injector.invoke(value, null, null, key);
                                    });
                                    if (angular.isDefined(template = nextRoute.template)) {
                                        if (angular.isFunction(template)) {
                                            template = template(nextRoute.params);
                                        }
                                    } else if (angular.isDefined(templateUrl = nextRoute.templateUrl)) {
                                        if (angular.isFunction(templateUrl)) {
                                            templateUrl = templateUrl(nextRoute.params);
                                        }
                                        if (angular.isDefined(templateUrl)) {
                                            nextRoute.loadedTemplateUrl = $sce.valueOf(templateUrl);
                                            template = $templateRequest(templateUrl);
                                        }
                                    }
                                    if (angular.isDefined(template)) {
                                        locals['$template'] = template;
                                    }
                                    return $q.all(locals);
                                }
                            }).
                            then(function(locals) {
                                if (nextRoute == $route.current) {
                                    if (nextRoute) {
                                        nextRoute.locals = locals;
                                        angular.copy(nextRoute.params, $routeParams);
                                    }
                                    $rootScope.$broadcast('$routeChangeSuccess', nextRoute, lastRoute);
                                }
                            }, function(error) {
                                if (nextRoute == $route.current) {
                                    $rootScope.$broadcast('$routeChangeError', nextRoute, lastRoute, error);
                                }
                            });
                        }
                    }
    
                    function parseRoute() {
                        var params, match;
                        angular.forEach(routes, function(route, path) {
                            if (!match && (params = switchRouteMatcher($location.path(), route))) {
                                match = inherit(route, {
                                    params: angular.extend({}, $location.search(), params),
                                    pathParams: params
                                });
                                match.$$route = route;
                            }
                        });
                        return match || routes[null] && inherit(routes[null], {
                            params: {},
                            pathParams: {}
                        });
                    }
    
                    function interpolate(string, params) {
                        var result = [];
                        angular.forEach((string || '').split(':'), function(segment, i) {
                            if (i === 0) {
                                result.push(segment);
                            } else {
                                var segmentMatch = segment.match(/(\w+)(?:[?*])?(.*)/);
                                var key = segmentMatch[1];
                                result.push(params[key]);
                                result.push(segmentMatch[2] || '');
                                delete params[key];
                            }
                        });
                        return result.join('');
                    }
                }
            ];
        }
        ngRouteModule.provider('$routeParams', $RouteParamsProvider);
    
        function $RouteParamsProvider() {
            this.$get = function() {
                return {};
            };
        }
        ngRouteModule.directive('ngView', ngViewFactory);
        ngRouteModule.directive('ngView', ngViewFillContentFactory);
        ngViewFactory.$inject = ['$route', '$anchorScroll', '$animate'];
    
        function ngViewFactory($route, $anchorScroll, $animate) {
            return {
                restrict: 'ECA',
                terminal: true,
                priority: 400,
                transclude: 'element',
                link: function(scope, $element, attr, ctrl, $transclude) {
                    var currentScope,
                        currentElement,
                        previousLeaveAnimation,
                        autoScrollExp = attr.autoscroll,
                        onloadExp = attr.onload || '';
                    scope.$on('$routeChangeSuccess', update);
                    update();
    
                    function cleanupLastView() {
                        if (previousLeaveAnimation) {
                            $animate.cancel(previousLeaveAnimation);
                            previousLeaveAnimation = null;
                        }
                        if (currentScope) {
                            currentScope.$destroy();
                            currentScope = null;
                        }
                        if (currentElement) {
                            previousLeaveAnimation = $animate.leave(currentElement);
                            previousLeaveAnimation.then(function() {
                                previousLeaveAnimation = null;
                            });
                            currentElement = null;
                        }
                    }
    
                    function update() {
                        var locals = $route.current && $route.current.locals,
                            template = locals && locals.$template;
                        if (angular.isDefined(template)) {
                            var newScope = scope.$new();
                            var current = $route.current;
                            var clone = $transclude(newScope, function(clone) {
                                $animate.enter(clone, null, currentElement || $element).then(function onNgViewEnter() {
                                    if (angular.isDefined(autoScrollExp) &&
                                        (!autoScrollExp || scope.$eval(autoScrollExp))) {
                                        $anchorScroll();
                                    }
                                });
                                cleanupLastView();
                            });
                            currentElement = clone;
                            currentScope = current.scope = newScope;
                            currentScope.$emit('$viewContentLoaded');
                            currentScope.$eval(onloadExp);
                        } else {
                            cleanupLastView();
                        }
                    }
                }
            };
        }
        ngViewFillContentFactory.$inject = ['$compile', '$controller', '$route'];
    
        function ngViewFillContentFactory($compile, $controller, $route) {
            return {
                restrict: 'ECA',
                priority: -400,
                link: function(scope, $element) {
                    var current = $route.current,
                        locals = current.locals;
                    $element.html(locals.$template);
                    var link = $compile($element.contents());
                    if (current.controller) {
                        locals.$scope = scope;
                        var controller = $controller(current.controller, locals);
                        if (current.controllerAs) {
                            scope[current.controllerAs] = controller;
                        }
                        $element.data('$ngControllerController', controller);
                        $element.children().data('$ngControllerController', controller);
                    }
                    scope[current.resolveAs || '$resolve'] = locals;
                    link(scope);
                }
            };
        }
    })(window, window.angular);;
    /*! RESOURCE: /scripts/angular_1.5.3/angular-touch.js */
    (function(window, angular, undefined) {
        'use strict';
        var ngTouch = angular.module('ngTouch', []);
        ngTouch.provider('$touch', $TouchProvider);
    
        function nodeName_(element) {
            return angular.lowercase(element.nodeName || (element[0] && element[0].nodeName));
        }
        $TouchProvider.$inject = ['$provide', '$compileProvider'];
    
        function $TouchProvider($provide, $compileProvider) {
            var ngClickOverrideEnabled = false;
            var ngClickDirectiveAdded = false;
            this.ngClickOverrideEnabled = function(enabled) {
                if (angular.isDefined(enabled)) {
                    if (enabled && !ngClickDirectiveAdded) {
                        ngClickDirectiveAdded = true;
                        ngTouchClickDirectiveFactory.$$moduleName = 'ngTouch';
                        $compileProvider.directive('ngClick', ngTouchClickDirectiveFactory);
                        $provide.decorator('ngClickDirective', ['$delegate', function($delegate) {
                            if (ngClickOverrideEnabled) {
                                $delegate.shift();
                            } else {
                                var i = $delegate.length - 1;
                                while (i >= 0) {
                                    if ($delegate[i].$$moduleName === 'ngTouch') {
                                        $delegate.splice(i, 1);
                                        break;
                                    }
                                    i--;
                                }
                            }
                            return $delegate;
                        }]);
                    }
                    ngClickOverrideEnabled = enabled;
                    return this;
                }
                return ngClickOverrideEnabled;
            };
            this.$get = function() {
                return {
                    ngClickOverrideEnabled: function() {
                        return ngClickOverrideEnabled;
                    }
                };
            };
        }
        ngTouch.factory('$swipe', [function() {
            var MOVE_BUFFER_RADIUS = 10;
            var POINTER_EVENTS = {
                'mouse': {
                    start: 'mousedown',
                    move: 'mousemove',
                    end: 'mouseup'
                },
                'touch': {
                    start: 'touchstart',
                    move: 'touchmove',
                    end: 'touchend',
                    cancel: 'touchcancel'
                }
            };
    
            function getCoordinates(event) {
                var originalEvent = event.originalEvent || event;
                var touches = originalEvent.touches && originalEvent.touches.length ? originalEvent.touches : [originalEvent];
                var e = (originalEvent.changedTouches && originalEvent.changedTouches[0]) || touches[0];
                return {
                    x: e.clientX,
                    y: e.clientY
                };
            }
    
            function getEvents(pointerTypes, eventType) {
                var res = [];
                angular.forEach(pointerTypes, function(pointerType) {
                    var eventName = POINTER_EVENTS[pointerType][eventType];
                    if (eventName) {
                        res.push(eventName);
                    }
                });
                return res.join(' ');
            }
            return {
                bind: function(element, eventHandlers, pointerTypes) {
                    var totalX, totalY;
                    var startCoords;
                    var lastPos;
                    var active = false;
                    pointerTypes = pointerTypes || ['mouse', 'touch'];
                    element.on(getEvents(pointerTypes, 'start'), function(event) {
                        startCoords = getCoordinates(event);
                        active = true;
                        totalX = 0;
                        totalY = 0;
                        lastPos = startCoords;
                        eventHandlers['start'] && eventHandlers['start'](startCoords, event);
                    });
                    var events = getEvents(pointerTypes, 'cancel');
                    if (events) {
                        element.on(events, function(event) {
                            active = false;
                            eventHandlers['cancel'] && eventHandlers['cancel'](event);
                        });
                    }
                    element.on(getEvents(pointerTypes, 'move'), function(event) {
                        if (!active) return;
                        if (!startCoords) return;
                        var coords = getCoordinates(event);
                        totalX += Math.abs(coords.x - lastPos.x);
                        totalY += Math.abs(coords.y - lastPos.y);
                        lastPos = coords;
                        if (totalX < MOVE_BUFFER_RADIUS && totalY < MOVE_BUFFER_RADIUS) {
                            return;
                        }
                        if (totalY > totalX) {
                            active = false;
                            eventHandlers['cancel'] && eventHandlers['cancel'](event);
                            return;
                        } else {
                            event.preventDefault();
                            eventHandlers['move'] && eventHandlers['move'](coords, event);
                        }
                    });
                    element.on(getEvents(pointerTypes, 'end'), function(event) {
                        if (!active) return;
                        active = false;
                        eventHandlers['end'] && eventHandlers['end'](getCoordinates(event), event);
                    });
                }
            };
        }]);
        var ngTouchClickDirectiveFactory = ['$parse', '$timeout', '$rootElement',
            function($parse, $timeout, $rootElement) {
                var TAP_DURATION = 750;
                var MOVE_TOLERANCE = 12;
                var PREVENT_DURATION = 2500;
                var CLICKBUSTER_THRESHOLD = 25;
                var ACTIVE_CLASS_NAME = 'ng-click-active';
                var lastPreventedTime;
                var touchCoordinates;
                var lastLabelClickCoordinates;
    
                function hit(x1, y1, x2, y2) {
                    return Math.abs(x1 - x2) < CLICKBUSTER_THRESHOLD && Math.abs(y1 - y2) < CLICKBUSTER_THRESHOLD;
                }
    
                function checkAllowableRegions(touchCoordinates, x, y) {
                    for (var i = 0; i < touchCoordinates.length; i += 2) {
                        if (hit(touchCoordinates[i], touchCoordinates[i + 1], x, y)) {
                            touchCoordinates.splice(i, i + 2);
                            return true;
                        }
                    }
                    return false;
                }
    
                function onClick(event) {
                    if (Date.now() - lastPreventedTime > PREVENT_DURATION) {
                        return;
                    }
                    var touches = event.touches && event.touches.length ? event.touches : [event];
                    var x = touches[0].clientX;
                    var y = touches[0].clientY;
                    if (x < 1 && y < 1) {
                        return;
                    }
                    if (lastLabelClickCoordinates &&
                        lastLabelClickCoordinates[0] === x && lastLabelClickCoordinates[1] === y) {
                        return;
                    }
                    if (lastLabelClickCoordinates) {
                        lastLabelClickCoordinates = null;
                    }
                    if (nodeName_(event.target) === 'label') {
                        lastLabelClickCoordinates = [x, y];
                    }
                    if (checkAllowableRegions(touchCoordinates, x, y)) {
                        return;
                    }
                    event.stopPropagation();
                    event.preventDefault();
                    event.target && event.target.blur && event.target.blur();
                }
    
                function onTouchStart(event) {
                    var touches = event.touches && event.touches.length ? event.touches : [event];
                    var x = touches[0].clientX;
                    var y = touches[0].clientY;
                    touchCoordinates.push(x, y);
                    $timeout(function() {
                        for (var i = 0; i < touchCoordinates.length; i += 2) {
                            if (touchCoordinates[i] == x && touchCoordinates[i + 1] == y) {
                                touchCoordinates.splice(i, i + 2);
                                return;
                            }
                        }
                    }, PREVENT_DURATION, false);
                }
    
                function preventGhostClick(x, y) {
                    if (!touchCoordinates) {
                        $rootElement[0].addEventListener('click', onClick, true);
                        $rootElement[0].addEventListener('touchstart', onTouchStart, true);
                        touchCoordinates = [];
                    }
                    lastPreventedTime = Date.now();
                    checkAllowableRegions(touchCoordinates, x, y);
                }
                return function(scope, element, attr) {
                    var clickHandler = $parse(attr.ngClick),
                        tapping = false,
                        tapElement,
                        startTime,
                        touchStartX,
                        touchStartY;
    
                    function resetState() {
                        tapping = false;
                        element.removeClass(ACTIVE_CLASS_NAME);
                    }
                    element.on('touchstart', function(event) {
                        tapping = true;
                        tapElement = event.target ? event.target : event.srcElement;
                        if (tapElement.nodeType == 3) {
                            tapElement = tapElement.parentNode;
                        }
                        element.addClass(ACTIVE_CLASS_NAME);
                        startTime = Date.now();
                        var originalEvent = event.originalEvent || event;
                        var touches = originalEvent.touches && originalEvent.touches.length ? originalEvent.touches : [originalEvent];
                        var e = touches[0];
                        touchStartX = e.clientX;
                        touchStartY = e.clientY;
                    });
                    element.on('touchcancel', function(event) {
                        resetState();
                    });
                    element.on('touchend', function(event) {
                        var diff = Date.now() - startTime;
                        var originalEvent = event.originalEvent || event;
                        var touches = (originalEvent.changedTouches && originalEvent.changedTouches.length) ?
                            originalEvent.changedTouches :
                            ((originalEvent.touches && originalEvent.touches.length) ? originalEvent.touches : [originalEvent]);
                        var e = touches[0];
                        var x = e.clientX;
                        var y = e.clientY;
                        var dist = Math.sqrt(Math.pow(x - touchStartX, 2) + Math.pow(y - touchStartY, 2));
                        if (tapping && diff < TAP_DURATION && dist < MOVE_TOLERANCE) {
                            preventGhostClick(x, y);
                            if (tapElement) {
                                tapElement.blur();
                            }
                            if (!angular.isDefined(attr.disabled) || attr.disabled === false) {
                                element.triggerHandler('click', [event]);
                            }
                        }
                        resetState();
                    });
                    element.onclick = function(event) {};
                    element.on('click', function(event, touchend) {
                        scope.$apply(function() {
                            clickHandler(scope, {
                                $event: (touchend || event)
                            });
                        });
                    });
                    element.on('mousedown', function(event) {
                        element.addClass(ACTIVE_CLASS_NAME);
                    });
                    element.on('mousemove mouseup', function(event) {
                        element.removeClass(ACTIVE_CLASS_NAME);
                    });
                };
            }
        ];
    
        function makeSwipeDirective(directiveName, direction, eventName) {
            ngTouch.directive(directiveName, ['$parse', '$swipe', function($parse, $swipe) {
                var MAX_VERTICAL_DISTANCE = 75;
                var MAX_VERTICAL_RATIO = 0.3;
                var MIN_HORIZONTAL_DISTANCE = 30;
                return function(scope, element, attr) {
                    var swipeHandler = $parse(attr[directiveName]);
                    var startCoords, valid;
    
                    function validSwipe(coords) {
                        if (!startCoords) return false;
                        var deltaY = Math.abs(coords.y - startCoords.y);
                        var deltaX = (coords.x - startCoords.x) * direction;
                        return valid &&
                            deltaY < MAX_VERTICAL_DISTANCE &&
                            deltaX > 0 &&
                            deltaX > MIN_HORIZONTAL_DISTANCE &&
                            deltaY / deltaX < MAX_VERTICAL_RATIO;
                    }
                    var pointerTypes = ['touch'];
                    if (!angular.isDefined(attr['ngSwipeDisableMouse'])) {
                        pointerTypes.push('mouse');
                    }
                    $swipe.bind(element, {
                        'start': function(coords, event) {
                            startCoords = coords;
                            valid = true;
                        },
                        'cancel': function(event) {
                            valid = false;
                        },
                        'end': function(coords, event) {
                            if (validSwipe(coords)) {
                                scope.$apply(function() {
                                    element.triggerHandler(eventName);
                                    swipeHandler(scope, {
                                        $event: event
                                    });
                                });
                            }
                        }
                    }, pointerTypes);
                };
            }]);
        }
        makeSwipeDirective('ngSwipeLeft', -1, 'swipeleft');
        makeSwipeDirective('ngSwipeRight', 1, 'swiperight');
    })(window, window.angular);;
    /*! RESOURCE: /scripts/angular_1.5.3/angular-cookies.js */
    (function(window, angular, undefined) {
        'use strict';
        angular.module('ngCookies', ['ng']).
        provider('$cookies', [function $CookiesProvider() {
            var defaults = this.defaults = {};
    
            function calcOptions(options) {
                return options ? angular.extend({}, defaults, options) : defaults;
            }
            this.$get = ['$$cookieReader', '$$cookieWriter', function($$cookieReader, $$cookieWriter) {
                return {
                    get: function(key) {
                        return $$cookieReader()[key];
                    },
                    getObject: function(key) {
                        var value = this.get(key);
                        return value ? angular.fromJson(value) : value;
                    },
                    getAll: function() {
                        return $$cookieReader();
                    },
                    put: function(key, value, options) {
                        $$cookieWriter(key, value, calcOptions(options));
                    },
                    putObject: function(key, value, options) {
                        this.put(key, angular.toJson(value), options);
                    },
                    remove: function(key, options) {
                        $$cookieWriter(key, undefined, calcOptions(options));
                    }
                };
            }];
        }]);
        angular.module('ngCookies').
        factory('$cookieStore', ['$cookies', function($cookies) {
            return {
                get: function(key) {
                    return $cookies.getObject(key);
                },
                put: function(key, value) {
                    $cookies.putObject(key, value);
                },
                remove: function(key) {
                    $cookies.remove(key);
                }
            };
        }]);
    
        function $$CookieWriter($document, $log, $browser) {
            var cookiePath = $browser.baseHref();
            var rawDocument = $document[0];
    
            function buildCookieString(name, value, options) {
                var path, expires;
                options = options || {};
                expires = options.expires;
                path = angular.isDefined(options.path) ? options.path : cookiePath;
                if (angular.isUndefined(value)) {
                    expires = 'Thu, 01 Jan 1970 00:00:00 GMT';
                    value = '';
                }
                if (angular.isString(expires)) {
                    expires = new Date(expires);
                }
                var str = encodeURIComponent(name) + '=' + encodeURIComponent(value);
                str += path ? ';path=' + path : '';
                str += options.domain ? ';domain=' + options.domain : '';
                str += expires ? ';expires=' + expires.toUTCString() : '';
                str += options.secure ? ';secure' : '';
                var cookieLength = str.length + 1;
                if (cookieLength > 4096) {
                    $log.warn("Cookie '" + name +
                        "' possibly not set or overflowed because it was too large (" +
                        cookieLength + " > 4096 bytes)!");
                }
                return str;
            }
            return function(name, value, options) {
                rawDocument.cookie = buildCookieString(name, value, options);
            };
        }
        $$CookieWriter.$inject = ['$document', '$log', '$browser'];
        angular.module('ngCookies').provider('$$cookieWriter', function $$CookieWriterProvider() {
            this.$get = $$CookieWriter;
        });
    })(window, window.angular);;
    /*! RESOURCE: /scripts/angular_1.5.3/angular-aria.js */
    (function(window, angular, undefined) {
        'use strict';
        var ngAriaModule = angular.module('ngAria', ['ng']).
        provider('$aria', $AriaProvider);
        var nodeBlackList = ['BUTTON', 'A', 'INPUT', 'TEXTAREA', 'SELECT', 'DETAILS', 'SUMMARY'];
        var isNodeOneOf = function(elem, nodeTypeArray) {
            if (nodeTypeArray.indexOf(elem[0].nodeName) !== -1) {
                return true;
            }
        };
    
        function $AriaProvider() {
            var config = {
                ariaHidden: true,
                ariaChecked: true,
                ariaDisabled: true,
                ariaRequired: true,
                ariaInvalid: true,
                ariaValue: true,
                tabindex: true,
                bindKeypress: true,
                bindRoleForClick: true
            };
            this.config = function(newConfig) {
                config = angular.extend(config, newConfig);
            };
    
            function watchExpr(attrName, ariaAttr, nodeBlackList, negate) {
                return function(scope, elem, attr) {
                    var ariaCamelName = attr.$normalize(ariaAttr);
                    if (config[ariaCamelName] && !isNodeOneOf(elem, nodeBlackList) && !attr[ariaCamelName]) {
                        scope.$watch(attr[attrName], function(boolVal) {
                            boolVal = negate ? !boolVal : !!boolVal;
                            elem.attr(ariaAttr, boolVal);
                        });
                    }
                };
            }
            this.$get = function() {
                return {
                    config: function(key) {
                        return config[key];
                    },
                    $$watchExpr: watchExpr
                };
            };
        }
        ngAriaModule.directive('ngShow', ['$aria', function($aria) {
                return $aria.$$watchExpr('ngShow', 'aria-hidden', [], true);
            }])
            .directive('ngHide', ['$aria', function($aria) {
                return $aria.$$watchExpr('ngHide', 'aria-hidden', [], false);
            }])
            .directive('ngValue', ['$aria', function($aria) {
                return $aria.$$watchExpr('ngValue', 'aria-checked', nodeBlackList, false);
            }])
            .directive('ngChecked', ['$aria', function($aria) {
                return $aria.$$watchExpr('ngChecked', 'aria-checked', nodeBlackList, false);
            }])
            .directive('ngRequired', ['$aria', function($aria) {
                return $aria.$$watchExpr('ngRequired', 'aria-required', nodeBlackList, false);
            }])
            .directive('ngModel', ['$aria', function($aria) {
                function shouldAttachAttr(attr, normalizedAttr, elem, allowBlacklistEls) {
                    return $aria.config(normalizedAttr) && !elem.attr(attr) && (allowBlacklistEls || !isNodeOneOf(elem, nodeBlackList));
                }
    
                function shouldAttachRole(role, elem) {
                    return !elem.attr('role') && (elem.attr('type') === role) && (elem[0].nodeName !== 'INPUT');
                }
    
                function getShape(attr, elem) {
                    var type = attr.type,
                        role = attr.role;
                    return ((type || role) === 'checkbox' || role === 'menuitemcheckbox') ? 'checkbox' :
                        ((type || role) === 'radio' || role === 'menuitemradio') ? 'radio' :
                        (type === 'range' || role === 'progressbar' || role === 'slider') ? 'range' : '';
                }
                return {
                    restrict: 'A',
                    require: 'ngModel',
                    priority: 200,
                    compile: function(elem, attr) {
                        var shape = getShape(attr, elem);
                        return {
                            pre: function(scope, elem, attr, ngModel) {
                                if (shape === 'checkbox') {
                                    ngModel.$isEmpty = function(value) {
                                        return value === false;
                                    };
                                }
                            },
                            post: function(scope, elem, attr, ngModel) {
                                var needsTabIndex = shouldAttachAttr('tabindex', 'tabindex', elem, false);
    
                                function ngAriaWatchModelValue() {
                                    return ngModel.$modelValue;
                                }
    
                                function getRadioReaction(newVal) {
                                    var boolVal = (attr.value == ngModel.$viewValue);
                                    elem.attr('aria-checked', boolVal);
                                }
    
                                function getCheckboxReaction() {
                                    elem.attr('aria-checked', !ngModel.$isEmpty(ngModel.$viewValue));
                                }
                                switch (shape) {
                                    case 'radio':
                                    case 'checkbox':
                                        if (shouldAttachRole(shape, elem)) {
                                            elem.attr('role', shape);
                                        }
                                        if (shouldAttachAttr('aria-checked', 'ariaChecked', elem, false)) {
                                            scope.$watch(ngAriaWatchModelValue, shape === 'radio' ?
                                                getRadioReaction : getCheckboxReaction);
                                        }
                                        if (needsTabIndex) {
                                            elem.attr('tabindex', 0);
                                        }
                                        break;
                                    case 'range':
                                        if (shouldAttachRole(shape, elem)) {
                                            elem.attr('role', 'slider');
                                        }
                                        if ($aria.config('ariaValue')) {
                                            var needsAriaValuemin = !elem.attr('aria-valuemin') &&
                                                (attr.hasOwnProperty('min') || attr.hasOwnProperty('ngMin'));
                                            var needsAriaValuemax = !elem.attr('aria-valuemax') &&
                                                (attr.hasOwnProperty('max') || attr.hasOwnProperty('ngMax'));
                                            var needsAriaValuenow = !elem.attr('aria-valuenow');
                                            if (needsAriaValuemin) {
                                                attr.$observe('min', function ngAriaValueMinReaction(newVal) {
                                                    elem.attr('aria-valuemin', newVal);
                                                });
                                            }
                                            if (needsAriaValuemax) {
                                                attr.$observe('max', function ngAriaValueMinReaction(newVal) {
                                                    elem.attr('aria-valuemax', newVal);
                                                });
                                            }
                                            if (needsAriaValuenow) {
                                                scope.$watch(ngAriaWatchModelValue, function ngAriaValueNowReaction(newVal) {
                                                    elem.attr('aria-valuenow', newVal);
                                                });
                                            }
                                        }
                                        if (needsTabIndex) {
                                            elem.attr('tabindex', 0);
                                        }
                                        break;
                                }
                                if (!attr.hasOwnProperty('ngRequired') && ngModel.$validators.required &&
                                    shouldAttachAttr('aria-required', 'ariaRequired', elem, false)) {
                                    attr.$observe('required', function() {
                                        elem.attr('aria-required', !!attr['required']);
                                    });
                                }
                                if (shouldAttachAttr('aria-invalid', 'ariaInvalid', elem, true)) {
                                    scope.$watch(function ngAriaInvalidWatch() {
                                        return ngModel.$invalid;
                                    }, function ngAriaInvalidReaction(newVal) {
                                        elem.attr('aria-invalid', !!newVal);
                                    });
                                }
                            }
                        };
                    }
                };
            }])
            .directive('ngDisabled', ['$aria', function($aria) {
                return $aria.$$watchExpr('ngDisabled', 'aria-disabled', nodeBlackList, false);
            }])
            .directive('ngMessages', function() {
                return {
                    restrict: 'A',
                    require: '?ngMessages',
                    link: function(scope, elem, attr, ngMessages) {
                        if (!elem.attr('aria-live')) {
                            elem.attr('aria-live', 'assertive');
                        }
                    }
                };
            })
            .directive('ngClick', ['$aria', '$parse', function($aria, $parse) {
                return {
                    restrict: 'A',
                    compile: function(elem, attr) {
                        var fn = $parse(attr.ngClick, null, true);
                        return function(scope, elem, attr) {
                            if (!isNodeOneOf(elem, nodeBlackList)) {
                                if ($aria.config('bindRoleForClick') && !elem.attr('role')) {
                                    elem.attr('role', 'button');
                                }
                                if ($aria.config('tabindex') && !elem.attr('tabindex')) {
                                    elem.attr('tabindex', 0);
                                }
                                if ($aria.config('bindKeypress') && !attr.ngKeypress) {
                                    elem.on('keypress', function(event) {
                                        var keyCode = event.which || event.keyCode;
                                        if (keyCode === 32 || keyCode === 13) {
                                            scope.$apply(callback);
                                        }
    
                                        function callback() {
                                            fn(scope, {
                                                $event: event
                                            });
                                        }
                                    });
                                }
                            }
                        };
                    }
                };
            }])
            .directive('ngDblclick', ['$aria', function($aria) {
                return function(scope, elem, attr) {
                    if ($aria.config('tabindex') && !elem.attr('tabindex') && !isNodeOneOf(elem, nodeBlackList)) {
                        elem.attr('tabindex', 0);
                    }
                };
            }]);
    })(window, window.angular);;
    /*! RESOURCE: /scripts/app/base/_module.js */
    angular.module('sn.base', ['sn.common.auth']);
    window.countWatchers = window.countWatchers || function(root) {
        var watchers = [];
        var f = function(element) {
            angular.forEach(['$scope', '$isolateScope'], function(scopeProperty) {
                if (element.data() && element.data().hasOwnProperty(scopeProperty)) {
                    angular.forEach(element.data()[scopeProperty].$$watchers, function(watcher) {
                        watchers.push(watcher);
                    });
                }
            });
            angular.forEach(element.children(), function(childElement) {
                f(angular.element(childElement));
            });
        };
        f(root);
        var watchersWithoutDuplicates = [];
        angular.forEach(watchers, function(item) {
            if (watchersWithoutDuplicates.indexOf(item) < 0) {
                watchersWithoutDuplicates.push(item);
            }
        });
        console.log(watchersWithoutDuplicates.length);
    };;
    /*! RESOURCE: /scripts/sn/common/auth/_module.js */
    angular.module('sn.common.auth', []);
    angular.module('sn.auth', ['sn.common.auth']);;
    /*! RESOURCE: /scripts/sn/common/auth/service.authInterceptor.js */
    angular.module('sn.common.auth').config(function($httpProvider) {
        $httpProvider.interceptors.push(function($rootScope, $q, $injector, $window, $log) {
            var LOG_PREFIX = '(authIntercepter) ';
    
            function error(response) {
                var status = response.status;
                if (status == 401) {
                    var newPromise = handle401(response);
                    if (newPromise)
                        return newPromise;
                }
                return $q.reject(response);
            }
    
            function handle401(response) {
                if (canResendRequest(response)) {
                    var deferredAgain = $q.defer();
                    var $http = $injector.get('$http');
                    $http(response.config).then(function success(newResponse) {
                        deferredAgain.resolve(newResponse);
                    }, function error(newResponse) {
                        deferredAgain.reject(newResponse);
                    });
                    return deferredAgain.promise;
                }
                $log.info(LOG_PREFIX + 'User has been logged out');
                $rootScope.$broadcast("@page.login");
                return null;
            }
    
            function canResendRequest(response) {
                var headers = response.headers();
                var requestToken = response.config.headers['X-UserToken'];
                if (!requestToken) {
                    requestToken = headers['x-usertoken-request'];
                }
                if ($window.g_ck && (requestToken !== $window.g_ck)) {
                    $log.info(LOG_PREFIX + 'Token refreshed since request -- retrying');
                    response.config.headers['X-UserToken'] = $window.g_ck;
                    return true;
                }
                if (headers['x-sessionloggedin'] != 'true')
                    return false;
                if (headers['x-usertoken-allowresubmit'] == 'false')
                    return false;
                var token = headers['x-usertoken-response'];
                if (token) {
                    $log.info(LOG_PREFIX + 'Received new token -- retrying');
                    response.config.headers['X-UserToken'] = token;
                    setToken(token);
                    return true;
                }
                return false;
            }
    
            function setToken(token) {
                $window.g_ck = token;
                if (!token) {
                    $httpProvider.defaults.headers.common["X-UserToken"] = 'token_intentionally_left_blank';
                } else {
                    $httpProvider.defaults.headers.common["X-UserToken"] = token;
                }
                if ($window.jQuery) {
                    jQuery.ajaxSetup({
                        headers: {
                            'X-UserToken': token
                        }
                    });
                }
                if ($window.Zepto) {
                    if (!Zepto.ajaxSettings.headers)
                        Zepto.ajaxSettings.headers = {};
                    Zepto.ajaxSettings.headers['X-UserToken'] = token;
                }
            }
            setToken($window.g_ck);
            return {
                responseError: error
            }
        });
    });;;
    /*! RESOURCE: /scripts/libs/angular-tooltips/angular-tooltips.min.js */
    /*
     * angular-tooltips
     * 1.0.7
     *
     * Angular.js tooltips module.
     * http://720kb.github.io/angular-tooltips
     *
     * MIT license
     * Tue Jan 26 2016
     */
    ! function(t, o) {
        "use strict";
        var e = "tooltips",
            i = function() {
                var t = [],
                    e = 0,
                    i = function(i) {
                        i - e >= 15 ? (t.forEach(function(t) {
                            t()
                        }), e = i) : o.console.log("Skipped!")
                    },
                    r = function() {
                        o.requestAnimationFrame(i)
                    },
                    l = function(o) {
                        o && t.push(o)
                    };
                return {
                    add: function(e) {
                        t.length || o.addEventListener("resize", r), l(e)
                    }
                }
            }(),
            r = function(t) {
                var o = {};
                return t.removeAttr(e), void 0 !== t.attr("tooltip-template") && (o["tooltip-template"] = t.attr("tooltip-template"), t.removeAttr("tooltip-template")), void 0 !== t.attr("tooltip-template-url") && (o["tooltip-template-url"] = t.attr("tooltip-template-url"), t.removeAttr("tooltip-template-url")), void 0 !== t.attr("tooltip-controller") && (o["tooltip-controller"] = t.attr("tooltip-controller"), t.removeAttr("tooltip-controller")), void 0 !== t.attr("tooltip-side") && (o["tooltip-side"] = t.attr("tooltip-side"), t.removeAttr("tooltip-side")), void 0 !== t.attr("tooltip-show-trigger") && (o["tooltip-show-trigger"] = t.attr("tooltip-show-trigger"), t.removeAttr("tooltip-show-trigger")), void 0 !== t.attr("tooltip-hide-trigger") && (o["tooltip-hide-trigger"] = t.attr("tooltip-hide-trigger"), t.removeAttr("tooltip-hide-trigger")), void 0 !== t.attr("tooltip-smart") && (o["tooltip-smart"] = t.attr("tooltip-smart"), t.removeAttr("tooltip-smart")), void 0 !== t.attr("tooltip-class") && (o["tooltip-class"] = t.attr("tooltip-class"), t.removeAttr("tooltip-class")), void 0 !== t.attr("tooltip-close-button") && (o["tooltip-close-button"] = t.attr("tooltip-close-button"), t.removeAttr("tooltip-close-button")), void 0 !== t.attr("tooltip-size") && (o["tooltip-size"] = t.attr("tooltip-size"), t.removeAttr("tooltip-size")), void 0 !== t.attr("tooltip-speed") && (o["tooltip-speed"] = t.attr("tooltip-speed"), t.removeAttr("tooltip-speed")), o
            },
            l = function(t) {
                return o.getComputedStyle ? o.getComputedStyle(t, "") : t.currentStyle ? t.currentStyle : void 0
            },
            a = function(e) {
                for (var i, r, l = o.document.querySelectorAll("._exradicated-tooltip"), a = 0, n = l.length; n > a; a += 1)
                    if (i = l.item(a), i && (r = t.element(i), r.data("_tooltip-parent") && r.data("_tooltip-parent") === e)) return r
            },
            n = function(t) {
                var o = a(t);
                o && o.remove()
            },
            s = function(t) {
                if (t) {
                    var e = t[0].getBoundingClientRect();
                    return e.top < 0 || e.top > o.document.body.offsetHeight || e.left < 0 || e.left > o.document.body.offsetWidth || e.bottom < 0 || e.bottom > o.document.body.offsetHeight || e.right < 0 || e.right > o.document.body.offsetWidth ? (t.css({
                        top: "",
                        left: "",
                        bottom: "",
                        right: ""
                    }), !0) : !1
                }
                throw new Error("You must provide a position")
            },
            p = function() {
                var t = {
                    side: "top",
                    showTrigger: "mouseover",
                    hideTrigger: "mouseleave",
                    "class": "",
                    smart: !1,
                    closeButton: !1,
                    size: "",
                    speed: "steady"
                };
                return {
                    configure: function(o) {
                        var e, i = Object.keys(t),
                            r = 0;
                        if (o)
                            for (; r < i.length; r += 1) e = i[r], e && o[e] && (t[e] = o[e])
                    },
                    $get: function() {
                        return t
                    }
                }
            },
            d = ["$log", "$http", "$compile", "$timeout", "$controller", "$injector", "tooltipsConf", function(e, p, d, c, m, u, g) {
                var f = function(e, u, f, v, h) {
                    if (f.tooltipTemplate && f.tooltipTemplateUrl) throw new Error("You can not define tooltip-template and tooltip-url together");
                    if (!f.tooltipTemplateUrl && !f.tooltipTemplate && f.tooltipController) throw new Error("You can not have a controller without a template or templateUrl defined");
                    var C, _ = "_" + g.side,
                        b = g.showTrigger,
                        y = g.hideTrigger,
                        w = g.size,
                        S = "_" + g.speed;
                    f.tooltipSide = f.tooltipSide || g.side, f.tooltipShowTrigger = f.tooltipShowTrigger || g.showTrigger, f.tooltipHideTrigger = f.tooltipHideTrigger || g.hideTrigger, f.tooltipClass = f.tooltipClass || g["class"], f.tooltipSmart = "true" === f.tooltipSmart || g.smart, f.tooltipCloseButton = f.tooltipCloseButton || g.closeButton.toString(), f.tooltipSize = f.tooltipSize || g.size, f.tooltipSpeed = f.tooltipSpeed || g.speed, f.tooltipAppendToBody = "true" === f.tooltipAppendToBody, h(e, function(e, g) {
                        var v = r(e),
                            h = t.element(o.document.createElement("tooltip")),
                            T = t.element(o.document.createElement("tip-cont")),
                            $ = t.element(o.document.createElement("tip")),
                            A = t.element(o.document.createElement("tip-tip")),
                            B = t.element(o.document.createElement("span")),
                            z = t.element(o.document.createElement("tip-arrow")),
                            E = function() {
                                return T.html()
                            },
                            k = function(t) {
                                void 0 !== t && T[0].getClientRects().length > 1 ? h.addClass("_multiline") : h.removeClass("_multiline")
                            },
                            P = function(e) {
                                if ($.addClass("_hidden"), f.tooltipSmart) switch (f.tooltipSide) {
                                    case "top":
                                        s($) && (h.removeClass("_top"), h.addClass("_left"), s($) && (h.removeClass("_left"), h.addClass("_bottom"), s($) && (h.removeClass("_bottom"), h.addClass("_right"), s($) && (h.removeClass("_right"), h.addClass("_top")))));
                                        break;
                                    case "left":
                                        s($) && (h.removeClass("_left"), h.addClass("_bottom"), s($) && (h.removeClass("_bottom"), h.addClass("_right"), s($) && (h.removeClass("_right"), h.addClass("_top"), s($) && (h.removeClass("_top"), h.addClass("_left")))));
                                        break;
                                    case "bottom":
                                        s($) && (h.removeClass("_bottom"), h.addClass("_left"), s($) && (h.removeClass("_left"), h.addClass("_top"), s($) && (h.removeClass("_top"), h.addClass("_right"), s($) && (h.removeClass("_right"), h.addClass("_bottom")))));
                                        break;
                                    case "right":
                                        s($) && (h.removeClass("_right"), h.addClass("_top"), s($) && (h.removeClass("_top"), h.addClass("_left"), s($) && (h.removeClass("_left"), h.addClass("_bottom"), s($) && (h.removeClass("_bottom"), h.addClass("_right")))));
                                        break;
                                    default:
                                        throw new Error("Position not supported")
                                }
                                if (f.tooltipAppendToBody) {
                                    var i, r, a, p, d, c = l(A[0]),
                                        m = l(z[0]),
                                        u = l($[0]),
                                        g = $[0].getBoundingClientRect(),
                                        v = t.copy($),
                                        C = 0,
                                        _ = c.length,
                                        b = 0,
                                        y = m.length,
                                        w = 0,
                                        S = u.length,
                                        T = {},
                                        B = {},
                                        E = {};
                                    for ($.removeClass("_hidden"), v.removeClass("_hidden"), v.data("_tooltip-parent", h), n(h); _ > C; C += 1) i = c[C], i && c.getPropertyValue(i) && (T[i] = c.getPropertyValue(i));
                                    for (; y > b; b += 1) i = m[b], i && m.getPropertyValue(i) && (E[i] = m.getPropertyValue(i));
                                    for (; S > w; w += 1) i = u[w], i && "position" !== i && "display" !== i && "opacity" !== i && "z-index" !== i && "bottom" !== i && "height" !== i && "left" !== i && "right" !== i && "top" !== i && "width" !== i && u.getPropertyValue(i) && (B[i] = u.getPropertyValue(i));
                                    r = o.parseInt(u.getPropertyValue("padding-top"), 10), a = o.parseInt(u.getPropertyValue("padding-bottom"), 10), p = o.parseInt(u.getPropertyValue("padding-left"), 10), d = o.parseInt(u.getPropertyValue("padding-right"), 10), B.top = g.top + o.scrollY + "px", B.left = g.left + o.scrollX + "px", B.height = g.height - (r + a) + "px", B.width = g.width - (p + d) + "px", v.css(B), v.children().css(T), v.children().next().css(E), e && "true" !== f.tooltipHidden && (v.addClass("_exradicated-tooltip"), t.element(o.document.body).append(v))
                                } else $.removeClass("_hidden"), e && "true" !== f.tooltipHidden && h.addClass("active")
                            },
                            x = function() {
                                f.tooltipAppendToBody ? n(h) : h.removeClass("active")
                            },
                            H = function it(t) {
                                var o, e = t.parent();
                                t[0] && (t[0].scrollHeight > t[0].clientHeight || t[0].scrollWidth > t[0].clientWidth) && t.on("scroll", function() {
                                    var t = this;
                                    o && c.cancel(o), o = c(function() {
                                        var o = a(h),
                                            e = h[0].getBoundingClientRect(),
                                            i = t.getBoundingClientRect();
                                        e.top < i.top || e.bottom > i.bottom || e.left < i.left || e.right > i.right ? n(h) : o && P(!0)
                                    })
                                }), e && e.length && it(e)
                            },
                            V = function(t) {
                                t && (A.empty(), A.append(B), A.append(t), c(function() {
                                    P()
                                }))
                            },
                            R = function(t) {
                                t && p.get(t).then(function(t) {
                                    t && t.data && (A.empty(), A.append(B), A.append(d(t.data)(g)), c(function() {
                                        P()
                                    }))
                                })
                            },
                            W = function(t) {
                                t && (_ && h.removeAttr("_" + _), h.addClass("_" + t), _ = t)
                            },
                            I = function(t) {
                                t && (b && h.off(b), h.on(t, P), b = t)
                            },
                            U = function(t) {
                                t && (y && h.off(y), h.on(t, x), y = t)
                            },
                            Y = function(t) {
                                t && (C && $.removeClass(C), $.addClass(t), C = t)
                            },
                            j = function() {
                                "boolean" != typeof f.tooltipSmart && (f.tooltipSmart = "true" === f.tooltipSmart)
                            },
                            q = function(t) {
                                var o = "true" === t;
                                o ? (B.on("click", x), B.css("display", "block")) : (B.off("click"), B.css("display", "none"))
                            },
                            O = function(o) {
                                if (o) {
                                    var e, i = m(o, {
                                            $scope: g
                                        }),
                                        r = g.$new(!1, g),
                                        l = o.indexOf("as");
                                    l >= 0 ? (e = o.substr(l + 3), r[e] = i) : t.extend(r, i), A.replaceWith(d(A)(r)), Z()
                                }
                            },
                            F = function(t) {
                                t && (w && A.removeClass("_" + w), A.addClass("_" + t), w = t)
                            },
                            L = function(t) {
                                t && (S && h.removeClass("_" + S), h.addClass("_" + t), S = t)
                            },
                            X = f.$observe("tooltipTemplate", V),
                            D = f.$observe("tooltipTemplateUrl", R),
                            G = f.$observe("tooltipSide", W),
                            J = f.$observe("tooltipShowTrigger", I),
                            K = f.$observe("tooltipHideTrigger", U),
                            M = f.$observe("tooltipClass", Y),
                            N = f.$observe("tooltipSmart", j),
                            Q = f.$observe("tooltipCloseButton", q),
                            Z = f.$observe("tooltipController", O),
                            tt = f.$observe("tooltipSize", F),
                            ot = f.$observe("tooltipSpeed", L),
                            et = g.$watch(E, k);
                        B.attr({
                            id: "close-button"
                        }), B.html("&times;"), $.addClass("_hidden"), A.append(B), A.append(f.tooltipTemplate), $.append(A), $.append(z), T.append(e), h.attr(v), h.addClass("tooltips"), h.append(T), h.append($), u.after(h), f.tooltipAppendToBody && (i.add(function() {
                            H(h)
                        }), H(h)), i.add(function() {
                            k(), P()
                        }), c(function() {
                            P(), $.removeClass("_hidden"), h.addClass("_ready")
                        }), g.$on("$destroy", function() {
                            X(), D(), G(), J(), K(), M(), N(), Q(), tt(), ot(), et(), e.off(f.tooltipShowTrigger + " " + f.tooltipHideTrigger)
                        })
                    })
                };
                return {
                    restrict: "A",
                    transclude: "element",
                    priority: 1,
                    terminal: !0,
                    link: f
                }
            }];
        t.module("720kb.tooltips", []).provider(e + "Conf", p).directive(e, d)
    }(angular, window);
    /*! RESOURCE: /scripts/sn/common/js_includes_common.js */
    /*! RESOURCE: /scripts/sn/common/_module.js */
    angular.module('sn.common', [
        'ngSanitize',
        'ngAnimate',
        'sn.common.avatar',
        'sn.common.controls',
        'sn.common.datetime',
        'sn.common.glide',
        'sn.common.i18n',
        'sn.common.link',
        'sn.common.mention',
        'sn.common.messaging',
        'sn.common.notification',
        'sn.common.presence',
        'sn.common.stream',
        'sn.common.ui',
        'sn.common.user_profile',
        'sn.common.util'
    ]);
    angular.module('ng.common', [
        'sn.common'
    ]);;
    /*! RESOURCE: /scripts/sn/common/dist/templates.js */
    angular.module('sn.common.dist.templates', []);;
    /*! RESOURCE: /scripts/sn/common/datetime/js_includes_datetime.js */
    /*! RESOURCE: /scripts/sn/common/datetime/_module.js */
    angular.module('sn.common.datetime', [
        'sn.common.i18n'
    ]);
    angular.module('sn.timeAgo', [
        'sn.common.datetime'
    ]);;
    /*! RESOURCE: /scripts/sn/common/datetime/directive.snTimeAgo.js */
    angular.module('sn.common.datetime').constant('DATE_GRANULARITY', {
        DATETIME: 1,
        DATE: 2
    });
    angular.module('sn.common.datetime').factory('timeAgoTimer', function($interval, $rootScope, DATE_GRANULARITY) {
        "use strict";
        var digestInterval;
        return function(displayGranularityType) {
            displayGranularityType = typeof displayGranularityType !== 'undefined' ? displayGranularityType : DATE_GRANULARITY.DATETIME;
            if (!digestInterval && displayGranularityType == DATE_GRANULARITY.DATETIME)
                digestInterval = $interval(function() {
                    $rootScope.$broadcast('sn.TimeAgo.tick');
                }, 30 * 1000);
            return Date.now();
        };
    });
    angular.module('sn.common.datetime').factory('timeAgo', function(timeAgoSettings, DATE_GRANULARITY) {
        var service = {
            settings: timeAgoSettings.get(),
            allowFuture: function allowFuture(bool) {
                this.settings.allowFuture = bool;
                return this;
            },
            toWords: function toWords(distanceMillis, messageGranularity) {
                messageGranularity = messageGranularity || DATE_GRANULARITY.DATETIME;
                var $l = service.settings.strings;
                var seconds = Math.abs(distanceMillis) / 1000;
                var minutes = seconds / 60;
                var hours = minutes / 60;
                var days = hours / 24;
                var years = days / 365;
                var prefix = $l.prefixAgo;
                var suffix = $l.suffixAgo;
                if ((seconds < 45 && messageGranularity == DATE_GRANULARITY.DATETIME) || (hours < 24 && messageGranularity == DATE_GRANULARITY.DATE))
                    prefix = suffix = '';
                if (service.settings.allowFuture) {
                    if (distanceMillis < 0) {
                        prefix = suffix = "";
                    }
                }
                if (!service.settings.allowFuture && distanceMillis < 0)
                    prefix = suffix = "";
    
                function substitute(stringOrFunction, number) {
                    var string = angular.isFunction(stringOrFunction) ?
                        stringOrFunction(number, distanceMillis) : stringOrFunction;
                    if (!string)
                        return "";
                    var value = ($l.numbers && $l.numbers[number]) || number;
                    return string.replace(/%d/i, value);
                }
                var wantDate = messageGranularity == DATE_GRANULARITY.DATE;
                var wantDateTime = messageGranularity == DATE_GRANULARITY.DATETIME;
                var words = distanceMillis <= 0 && wantDateTime && substitute($l.justNow, 0) ||
                    distanceMillis <= 0 && wantDate && substitute($l.today, 0) ||
                    seconds < 45 && (distanceMillis >= 0 || !service.settings.allowFuture) && wantDateTime && substitute($l.justNow, Math.round(seconds)) ||
                    seconds < 45 && wantDateTime && substitute($l.seconds, Math.round(seconds)) ||
                    seconds < 90 && wantDateTime && substitute($l.minute, 1) ||
                    minutes < 45 && wantDateTime && substitute($l.minutes, Math.round(minutes)) ||
                    minutes < 90 && wantDateTime && substitute($l.hour, 1) ||
                    hours < 24 && wantDateTime && substitute($l.hours, Math.round(hours)) ||
                    hours < 24 && wantDate && substitute($l.today, 0) ||
                    hours < 42 && substitute($l.day, 1) ||
                    days < 30 && substitute($l.days, Math.ceil(days)) ||
                    days < 45 && substitute($l.month, 1) ||
                    days < 365 && substitute($l.months, Math.round(days / 30)) ||
                    years < 1.5 && substitute($l.year, 1) ||
                    substitute($l.years, Math.round(years));
                var separator = $l.wordSeparator === undefined ? " " : $l.wordSeparator;
                return [prefix, words, suffix].join(separator).trim();
            },
            parse: function(iso8601) {
                if (angular.isNumber(iso8601))
                    return new Date(parseInt(iso8601, 10));
                var s = iso8601.trim();
                s = s.replace(/\.\d+/, "");
                s = s.replace(/-/, "/").replace(/-/, "/");
                s = s.replace(/T/, " ").replace(/Z/, " UTC");
                s = s.replace(/([\+\-]\d\d)\:?(\d\d)/, " $1$2");
                return new Date(s);
            }
        };
        return service;
    });
    angular.module('sn.common.datetime').directive("snTimeAgo", function(timeAgoSettings, $rootScope, timeAgo, timeAgoTimer, DATE_GRANULARITY) {
        "use strict";
        return {
            restrict: "E",
            template: '<time title="{{ ::titleTime }}">{{timeAgo}}</time>',
            scope: {
                timestamp: "=",
                timezone: "@",
                local: "="
            },
            link: function(scope) {
                timeAgoSettings.ready.then(function() {
                    timeAgoTimer(DATE_GRANULARITY.DATETIME)
                    scope.$on('sn.TimeAgo.tick', setTimeAgo);
                    setTimeAgo();
                });
    
                function setTimeAgo() {
                    scope.timeAgo = timeAgoConverter(scope.timestamp, true);
                }
    
                function timeAgoConverter(input, noFuture) {
                    if (!input)
                        return;
                    var allowFuture = !noFuture;
                    var date = timeAgo.parse(input);
                    if (scope.local) {
                        scope.titleTime = input;
                        return timeAgo.allowFuture(allowFuture).toWords(new Date() - date);
                    }
                    if (scope.timezone) {
                        var clientOffset = new Date().getTimezoneOffset() * -60000;
                        var sessionOffset = Number(scope.timezone.substring(scope.timezone.indexOf("offset=") + 7, scope.timezone.indexOf(",dstSavings")));
                        if (clientOffset != sessionOffset)
                            date = new Date(date - sessionOffset);
                        else
                            date = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
                    }
                    if (Object.prototype.toString.call(date) !== "[object Date]" && Object.prototype.toString.call(date) !== "[object Number]")
                        return input;
                    else if (Object.prototype.toString.call(date) == "[object Date]" && isNaN(date.getTime()))
                        return input;
                    setTitleTime(date);
                    var currentDate = new Date();
                    currentDate = new Date(currentDate.getUTCFullYear(), currentDate.getUTCMonth(), currentDate.getUTCDate(), currentDate.getUTCHours(), currentDate.getUTCMinutes(), currentDate.getUTCSeconds());
                    var diff = currentDate - date;
                    return timeAgo.allowFuture(allowFuture).toWords(diff);
                }
    
                function setTitleTime(date) {
                    var t = date.getTime();
                    var o = date.getTimezoneOffset();
                    t -= o * 60 * 1000;
                    scope.titleTime = new Date(t).toLocaleString();
                }
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/datetime/directive.snDayAgo.js */
    angular.module('sn.common.datetime').directive("snDayAgo", function(timeAgoSettings, $rootScope, timeAgo, timeAgoTimer, DATE_GRANULARITY) {
        "use strict";
        return {
            restrict: "E",
            template: '<time>{{dayAgo}}</time>',
            scope: {
                date: "="
            },
            link: function(scope) {
                timeAgoSettings.ready.then(function() {
                    setDayAgo();
                });
    
                function setDayAgo() {
                    scope.dayAgo = dayAgoConverter(scope.date, "noFuture");
                }
    
                function dayAgoConverter(input, option) {
                    if (!input) return;
                    var allowFuture = !((option === 'noFuture') || (option === 'no_future'));
                    var date = timeAgo.parse(input);
                    if (Object.prototype.toString.call(date) !== "[object Date]")
                        return input;
                    else if (isNaN(date.getTime()))
                        return input;
                    var diff = timeAgoTimer(DATE_GRANULARITY.DATE) - date;
                    return timeAgo.allowFuture(allowFuture).toWords(diff, DATE_GRANULARITY.DATE);
                }
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/datetime/snTimeAgoSettings.js */
    angular.module('sn.common.datetime').provider('snTimeAgoSettings', function() {
        "use strict";
        var INIT_NEVER = 'never';
        var INIT_AUTO = 'auto';
        var INIT_MANUAL = 'manual';
        var _initMethod = INIT_AUTO;
        this.setInitializationMethod = function(init) {
            switch (init) {
                default: init = INIT_AUTO;
                case INIT_NEVER:
                        case INIT_AUTO:
                        case INIT_MANUAL:
                        _initMethod = init;
                    break;
            }
        };
        this.$get = function(i18n, $q) {
            var settings = {
                allowFuture: true,
                dateOnly: false,
                strings: {}
            };
            var _initialized = false;
            var ready = $q.defer();
    
            function initialize() {
                if (_initMethod === INIT_NEVER) {
                    return $q.reject();
                }
                if (!_initialized) {
                    _initialized = true;
                    i18n.getMessages(['prefix_ago', 'prefix_from now', 'suffix_ago', 'suffix_from now', 'just now',
                        'less than a minute', 'about a minute', '%d minutes', 'about an hour', 'about %d hours', 'today', 'a day', '%d days',
                        'about a month', '%d months', 'about a year', 'about a year', '%d years'
                    ], function(msgs) {
                        settings.strings = {
                            prefixAgo: msgs['prefix_ago'],
                            prefixFromNow: msgs['prefix_from now'],
                            suffixAgo: msgs['suffix_ago'],
                            suffixFromNow: msgs["suffix_from now"],
                            justNow: msgs["just now"],
                            seconds: msgs["less than a minute"],
                            minute: msgs["about a minute"],
                            minutes: msgs["%d minutes"],
                            hour: msgs["about an hour"],
                            hours: msgs["about %d hours"],
                            day: msgs["a day"],
                            days: msgs["%d days"],
                            month: msgs["about a month"],
                            months: msgs["%d months"],
                            year: msgs["about a year"],
                            years: msgs["%d years"],
                            today: msgs["today"],
                            wordSeparator: msgs["timeago_number_separator"],
                            numbers: []
                        };
                        ready.resolve();
                    });
                }
                return ready.promise;
            }
            if (_initMethod === INIT_AUTO) {
                initialize();
            }
            return {
                initialize: initialize,
                ready: ready.promise,
                get: function get() {
                    return settings;
                },
                set: function set(translated) {
                    settings = angular.extend(settings, translated);
                }
            };
        };
    }).factory('timeAgoSettings', function(snTimeAgoSettings) {
        return snTimeAgoSettings;
    });;;
    /*! RESOURCE: /scripts/sn/common/glide/js_includes_glide.js */
    /*! RESOURCE: /scripts/sn/common/glide/_module.js */
    angular.module('sn.common.glide', [
        'sn.common.util'
    ]);;
    /*! RESOURCE: /scripts/sn/common/glide/factory.glideUrlBuilder.js */
    angular.module('sn.common.glide').factory('glideUrlBuilder', ['$window', function($window) {
        "use strict";
    
        function GlideUrl(contextPath) {
            var objDef = {
                contextPath: '',
                params: {},
                encodedString: '',
                encode: true,
                setFromCurrent: function() {
                    this.setFromString($window.location.href);
                },
                setFromString: function(href) {
                    var pos = href.indexOf('?');
                    if (pos < 0) {
                        this.contextPath = href;
                        return;
                    }
                    this.contextPath = href.slice(0, pos);
                    var hashes = href.slice(pos + 1).split('&');
                    var i = hashes.length;
                    while (i--) {
                        var pos = hashes[i].indexOf('=');
                        this.params[hashes[i].substring(0, pos)] = hashes[i].substring(++pos);
                    }
                },
                setContextPath: function(c) {
                    this.contextPath = c;
                },
                getParam: function(p) {
                    return this.params[p];
                },
                getParams: function() {
                    return this.params;
                },
                addParam: function(name, value) {
                    this.params[name] = value;
                    return this;
                },
                addToken: function() {
                    if (typeof g_ck != 'undefined' && g_ck != "")
                        this.addParam('sysparm_ck', g_ck);
                    return this;
                },
                deleteParam: function(name) {
                    delete this.params[name];
                },
                addEncodedString: function(s) {
                    if (!s)
                        return;
                    if (s.substr(0, 1) != "&")
                        this.encodedString += "&";
                    this.encodedString += s;
                    return this;
                },
                getQueryString: function(additionalParams) {
                    var qs = this._getParamsForURL(this.params);
                    qs += this._getParamsForURL(additionalParams);
                    qs += this.encodedString;
                    if (qs.length == 0)
                        return "";
                    return qs.substring(1);
                },
                _getParamsForURL: function(params) {
                    if (!params)
                        return '';
                    var url = '';
                    for (var n in params) {
                        var p = params[n] || '';
                        url += '&' + n + '=' + (this.encode ? encodeURIComponent(p + '') : p);
                    }
                    return url;
                },
                getURL: function(additionalParams) {
                    var url = this.contextPath;
                    var qs = this.getQueryString(additionalParams);
                    if (qs)
                        url += "?" + qs;
                    return url;
                },
                setEncode: function(b) {
                    this.encode = b;
                },
                toString: function() {
                    return 'GlideURL';
                }
            }
            return objDef;
        }
        return {
            newGlideUrl: function(contextPath) {
                var glideUrl = new GlideUrl();
                glideUrl.setFromString(contextPath ? contextPath : '');
                return glideUrl;
            },
            refresh: function() {
                $window.location.replace($window.location.href);
            },
            getCancelableLink: function(link) {
                if ($window.NOW && $window.NOW.g_cancelPreviousTransaction) {
                    var nextChar = link.indexOf('?') > -1 ? '&' : '?';
                    link += nextChar + "sysparm_cancelable=true";
                }
                return link;
            }
        };
    }]);;
    /*! RESOURCE: /scripts/sn/common/glide/service.queryFilter.js */
    angular.module('sn.common.glide').factory('queryFilter', function() {
        "use strict";
        return {
            create: function() {
                var that = {};
                that.conditions = [];
    
                function newCondition(field, operator, value, label, displayValue, type) {
                    var condition = {
                        field: field,
                        operator: operator,
                        value: value,
                        displayValue: displayValue,
                        label: label,
                        left: null,
                        right: null,
                        type: null,
                        setValue: function(value, displayValue) {
                            this.value = value;
                            this.displayValue = displayValue ? displayValue : value;
                        }
                    };
                    if (type)
                        condition.type = type;
                    return condition;
                }
    
                function addCondition(condition) {
                    that.conditions.push(condition);
                    return condition;
                }
    
                function removeCondition(condition) {
                    for (var i = that.conditions.length - 1; i >= 0; i--) {
                        if (that.conditions[i] === condition)
                            that.conditions.splice(i, 1);
                    }
                }
    
                function getConditionsByField(conditions, field) {
                    var conditionsToReturn = [];
                    for (var condition in conditions) {
                        if (conditions.hasOwnProperty(condition)) {
                            if (conditions[condition].field == field)
                                conditionsToReturn.push(conditions[condition]);
                        }
                    }
                    return conditionsToReturn;
                }
    
                function encodeCondition(condition) {
                    var output = "";
                    if (condition.hasOwnProperty("left") && condition.left) {
                        output += encodeCondition(condition.left);
                    }
                    if (condition.hasOwnProperty("right") && condition.right) {
                        var right = encodeCondition(condition.right);
                        if (right.length > 0) {
                            output += "^" + condition.type + right;
                        }
                    }
                    if (condition.field) {
                        output += condition.field;
                        output += condition.operator;
                        if (condition.value !== null && typeof condition.value !== "undefined")
                            output += condition.value;
                    }
                    return output;
                }
    
                function createEncodedQuery() {
                    var eq = "";
                    var ca = that.conditions;
                    for (var i = 0; i < ca.length; i++) {
                        var condition = ca[i];
                        if (eq.length)
                            eq += '^';
                        eq += encodeCondition(condition);
                    }
                    eq += "^EQ";
                    return eq;
                }
                that.addCondition = addCondition;
                that.newCondition = newCondition;
                that.createEncodedQuery = createEncodedQuery;
                that.getConditionsByField = getConditionsByField;
                that.removeCondition = removeCondition;
                return that;
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/glide/service.filterExpressionParser.js */
    angular.module('sn.common.glide').factory('filterExpressionParser', function() {
        'use strict';
        var operatorExpressions = [{
            wildcardExp: '(.*)',
            operator: 'STARTSWITH',
            toExpression: function(filter) {
                return filter;
            }
        }, {
            wildcardExp: '^\\*(.*)',
            operator: 'LIKE',
            toExpression: function(filter) {
                return (filter === '*' ? filter : '*' + filter);
            }
        }, {
            wildcardExp: '^\\.(.*)',
            operator: 'LIKE',
            toExpression: function(filter) {
                return '.' + filter;
            }
        }, {
            wildcardExp: '^%(.*)',
            operator: 'ENDSWITH',
            toExpression: function(filter) {
                return (filter === '%' ? filter : '%' + filter);
            }
        }, {
            wildcardExp: '(.*)%',
            operator: 'LIKE',
            toExpression: function(filter) {
                return filter + '%';
            }
        }, {
            wildcardExp: '^=(.*)',
            operator: '=',
            toExpression: function(filter) {
                return (filter === '=' ? filter : '=' + filter);
            }
        }, {
            wildcardExp: '^!\\*(.*)',
            operator: 'NOT LIKE',
            toExpression: function(filter) {
                return (filter === '!*' || filter === '!' ? filter : '!*' + filter);
            }
        }, {
            wildcardExp: '^!=(.*)',
            operator: '!=',
            toExpression: function(filter) {
                return (filter === '!=' || filter === '!' ? filter : '!=' + filter);
            }
        }];
        return {
            getOperatorExpressionForOperator: function(operator) {
                for (var i = 0; i < operatorExpressions.length; i++) {
                    var item = operatorExpressions[i];
                    if (item.operator === operator)
                        return item;
                }
                throw {
                    name: 'OperatorNotSupported',
                    message: 'The operator ' + operator + ' is not in the list of operatorExpressions.'
                };
            },
            parse: function(val, defaultOperator) {
                var parsedValue = {
                    filterText: val,
                    operator: defaultOperator || 'STARTSWITH'
                };
                for (var i = 1; i < operatorExpressions.length; i++) {
                    var operatorItem = operatorExpressions[i];
                    var match = val.match(operatorItem.wildcardExp);
                    if (match && match[1] !== '') {
                        parsedValue.operator = operatorItem.operator;
                        parsedValue.filterText = match[1];
                    }
                }
                return parsedValue;
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/glide/service.userPreferences.js */
    angular.module('sn.common.glide').factory("userPreferences", function($http, $q, unwrappedHTTPPromise, urlTools) {
        "use strict";
        var preferencesCache = {};
    
        function getPreference(preferenceName) {
            if (preferenceName in preferencesCache)
                return preferencesCache[preferenceName];
            var targetURL = urlTools.getURL('user_preference', {
                    "sysparm_pref_name": preferenceName,
                    "sysparm_action": "get"
                }),
                deferred = $q.defer();
            $http.get(targetURL).success(function(response) {
                deferred.resolve(response.sysparm_pref_value);
            }).error(function(data, status) {
                deferred.reject("Error getting preference " + preferenceName + ": " + status);
            });
            preferencesCache[preferenceName] = deferred.promise;
            return deferred.promise;
        }
    
        function setPreference(preferenceName, preferenceValue) {
            var targetURL = urlTools.getURL('user_preference', {
                "sysparm_pref_name": preferenceName,
                "sysparm_action": "set",
                "sysparm_pref_value": "" + preferenceValue
            });
            var httpPromise = $http.get(targetURL);
            addToCache(preferenceName, preferenceValue);
            return unwrappedHTTPPromise(httpPromise);
        }
    
        function addToCache(preferenceName, preferenceValue) {
            preferencesCache[preferenceName] = $q.when(preferenceValue);
        }
        var userPreferences = {
            getPreference: getPreference,
            setPreference: setPreference,
            addToCache: addToCache
        };
        return userPreferences;
    });;
    /*! RESOURCE: /scripts/sn/common/glide/service.nowStream.js */
    angular.module('sn.common.glide').constant('nowStreamTimerInterval', 5000);
    angular.module('sn.common.glide').factory('nowStream', function($q, $timeout, urlTools, nowStreamTimerInterval, snResource, $log) {
        'use strict';
        var Stream = function() {
            this.initialize.apply(this, arguments);
        };
        Stream.prototype = {
            initialize: function(table, query, sys_id, processor, interval, source, includeAttachments) {
                this.table = table;
                this.query = query;
                this.sysparmQuery = null;
                this.sys_id = sys_id;
                this.processor = processor;
                this.lastTimestamp = 0;
                this.inflightRequest = null;
                this.requestImmediateUpdate = false;
                this.interval = interval;
                this.source = source;
                this.includeAttachments = includeAttachments;
                this.stopped = true;
            },
            setQuery: function(sysparmQuery) {
                this.sysparmQuery = sysparmQuery;
            },
            poll: function(callback, preRequestCallback) {
                this.callback = callback;
                this.preRequestCallback = preRequestCallback;
                this._stopPolling();
                this._startPolling();
            },
            tap: function() {
                if (!this.inflightRequest) {
                    this._stopPolling();
                    this._startPolling();
                } else
                    this.requestImmediateUpdate = true;
            },
            insert: function(field, text) {
                this.insertForEntry(field, text, this.table, this.sys_id);
            },
            insertForEntry: function(field, text, table, sys_id) {
                return this.insertEntries([{
                    field: field,
                    text: text
                }], table, sys_id);
            },
            expandMentions: function(entryText, mentionIDMap) {
                return entryText.replace(/@\[(.+?)\]/gi, function(mention) {
                    var mentionedName = mention.substring(2, mention.length - 1);
                    if (mentionIDMap[mentionedName]) {
                        return "@[" + mentionIDMap[mentionedName] + ":" + mentionedName + "]";
                    } else {
                        return mention;
                    }
                });
            },
            insertEntries: function(entries, table, sys_id, mentionIDMap) {
                mentionIDMap = mentionIDMap || {};
                var sanitizedEntries = [];
                for (var i = 0; i < entries.length; i++) {
                    var entryText = entries[i].text;
                    if (entryText && entryText.endsWith('\n'))
                        entryText = entryText.substring(0, entryText.length - 1);
                    if (!entryText)
                        continue;
                    entries[i].text = this.expandMentions(entryText, mentionIDMap);
                    sanitizedEntries.push(entries[i]);
                }
                if (sanitizedEntries.length === 0)
                    return;
                this._isInserting = true;
                var url = this._getInsertURL(table, sys_id);
                var that = this;
                return snResource().post(url, {
                    entries: sanitizedEntries
                }).then(this._successCallback.bind(this), function() {
                    $log.warn('Error submitting entries', sanitizedEntries);
                }).then(function() {
                    that._isInserting = false;
                });
            },
            cancel: function() {
                this._stopPolling();
            },
            _startPolling: function() {
                var interval = this._getInterval();
                var that = this;
                var successCallback = this._successCallback.bind(this);
                that.stopped = false;
    
                function runPoll() {
                    if (that._isInserting) {
                        establishNextRequest();
                        return;
                    }
                    if (!that.inflightRequest) {
                        that.inflightRequest = that._executeRequest();
                        that.inflightRequest.then(successCallback);
                        that.inflightRequest.finally(function() {
                            that.inflightRequest = null;
                            if (that.requestImmediateUpdate) {
                                that.requestImmediateUpdate = false;
                                establishNextRequest(0);
                            } else {
                                establishNextRequest();
                            }
                        });
                    }
                }
    
                function establishNextRequest(intervalOverride) {
                    if (that.stopped)
                        return;
                    intervalOverride = (parseFloat(intervalOverride) >= 0) ? intervalOverride : interval;
                    $timeout.cancel(that.timer);
                    that.timer = $timeout(runPoll, intervalOverride);
                }
                runPoll();
            },
            _stopPolling: function() {
                if (this.timer)
                    $timeout.cancel(this.timer);
                this.stopped = true;
            },
            _executeRequest: function() {
                var url = this._getURL();
                if (this.preRequestCallback) {
                    this.preRequestCallback();
                }
                return snResource().get(url);
            },
            _getURL: function() {
                var params = {
                    table: this.table,
                    action: this._getAction(),
                    sysparm_silent_request: true,
                    sysparm_auto_request: true,
                    sysparm_timestamp: this.lastTimestamp,
                    include_attachments: this.includeAttachments
                };
                if (this.sys_id) {
                    params['sys_id'] = this.sys_id;
                } else if (this.sysparmQuery) {
                    params['sysparm_query'] = this.sysparmQuery;
                }
                var url = urlTools.getURL(this.processor, params);
                if (!this.sys_id) {
                    url += "&p=" + this.query;
                }
                return url;
            },
            _getInsertURL: function(table, sys_id) {
                return urlTools.getURL(this.processor, {
                    action: 'insert',
                    table: table,
                    sys_id: sys_id,
                    sysparm_timestamp: this.timestamp || 0,
                    sysparm_source: this.source
                });
            },
            _successCallback: function(response) {
                var response = response.data;
                if (response.entries && response.entries.length) {
                    response.entries = this._filterOld(response.entries);
                    if (response.entries.length > 0) {
                        this.lastEntry = angular.copy(response.entries[0]);
                        this.lastTimestamp = response.sys_timestamp || response.entries[0].sys_timestamp;
                    }
                }
                this.callback.call(null, response);
            },
            _filterOld: function(entries) {
                for (var i = 0; i < entries.length; i++) {
                    if (entries[i].sys_timestamp == this.lastTimestamp) {
                        if (!angular.equals(this._makeComparable(entries[i]), this._makeComparable(this.lastEntry)))
                            continue;
                    }
                    if (entries[i].sys_timestamp <= this.lastTimestamp)
                        return entries.slice(0, i);
                }
                return entries;
            },
            _makeComparable: function(entry) {
                var copy = angular.copy(entry);
                delete copy.short_description;
                delete copy.display_value;
                return copy;
            },
            _getAction: function() {
                return this.sys_id ? 'get_new_entries' : 'get_set_entries';
            },
            _getInterval: function() {
                if (this.interval)
                    return this.interval;
                else if (window.NOW && NOW.stream_poll_interval)
                    return NOW.stream_poll_interval * 1000;
                else
                    return nowStreamTimerInterval;
            }
        };
        return {
            create: function(table, query, sys_id, processor, interval, source) {
                return new Stream(table, query, sys_id, processor, interval, source);
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/glide/service.nowServer.js */
    angular.module('sn.common.glide').factory('nowServer', function($http, $q, userPreferences, angularProcessorUrl, urlTools) {
        return {
            getBaseURL: function() {
                return angularProcessorUrl;
            },
            getPartial: function(scope, partial, parms, callback) {
                var url = this.getPartialURL(partial, parms);
                if (url === scope.url) {
                    callback.call();
                    return;
                }
                var fn = scope.$on('$includeContentLoaded', function() {
                    fn.call();
                    callback.call();
                });
                scope.url = url;
            },
            replaceView: function($location, newView) {
                var p = $location.path();
                var a = p.split("/");
                a[1] = newView;
                p = a.join("/");
                return p;
            },
            getPartialURL: urlTools.getPartialURL,
            getURL: urlTools.getURL,
            urlFor: urlTools.urlFor,
            getPropertyURL: urlTools.getPropertyURL,
            setPreference: userPreferences.setPreference,
            getPreference: userPreferences.getPreference
        }
    });;;
    /*! RESOURCE: /scripts/sn/common/avatar/js_includes_avatar.js */
    /*! RESOURCE: /scripts/sn/common/presence/js_includes_presence.js */
    /*! RESOURCE: /scripts/js_includes_ng_amb.js */
    /*! RESOURCE: /scripts/js_includes_amb.js */
    /*! RESOURCE: /scripts/thirdparty/cometd/jquery/jquery-1.11.0.min.js */
    /*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
    ! function(a, b) {
        "object" == typeof module && "object" == typeof module.exports ? module.exports = a.document ? b(a, !0) : function(a) {
            if (!a.document) throw new Error("jQuery requires a window with a document");
            return b(a)
        } : b(a)
    }("undefined" != typeof window ? window : this, function(a, b) {
        var c = [],
            d = c.slice,
            e = c.concat,
            f = c.push,
            g = c.indexOf,
            h = {},
            i = h.toString,
            j = h.hasOwnProperty,
            k = "".trim,
            l = {},
            m = "1.11.0",
            n = function(a, b) {
                return new n.fn.init(a, b)
            },
            o = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
            p = /^-ms-/,
            q = /-([\da-z])/gi,
            r = function(a, b) {
                return b.toUpperCase()
            };
        n.fn = n.prototype = {
            jquery: m,
            constructor: n,
            selector: "",
            length: 0,
            toArray: function() {
                return d.call(this)
            },
            get: function(a) {
                return null != a ? 0 > a ? this[a + this.length] : this[a] : d.call(this)
            },
            pushStack: function(a) {
                var b = n.merge(this.constructor(), a);
                return b.prevObject = this, b.context = this.context, b
            },
            each: function(a, b) {
                return n.each(this, a, b)
            },
            map: function(a) {
                return this.pushStack(n.map(this, function(b, c) {
                    return a.call(b, c, b)
                }))
            },
            slice: function() {
                return this.pushStack(d.apply(this, arguments))
            },
            first: function() {
                return this.eq(0)
            },
            last: function() {
                return this.eq(-1)
            },
            eq: function(a) {
                var b = this.length,
                    c = +a + (0 > a ? b : 0);
                return this.pushStack(c >= 0 && b > c ? [this[c]] : [])
            },
            end: function() {
                return this.prevObject || this.constructor(null)
            },
            push: f,
            sort: c.sort,
            splice: c.splice
        }, n.extend = n.fn.extend = function() {
            var a, b, c, d, e, f, g = arguments[0] || {},
                h = 1,
                i = arguments.length,
                j = !1;
            for ("boolean" == typeof g && (j = g, g = arguments[h] || {}, h++), "object" == typeof g || n.isFunction(g) || (g = {}), h === i && (g = this, h--); i > h; h++)
                if (null != (e = arguments[h]))
                    for (d in e) a = g[d], c = e[d], g !== c && (j && c && (n.isPlainObject(c) || (b = n.isArray(c))) ? (b ? (b = !1, f = a && n.isArray(a) ? a : []) : f = a && n.isPlainObject(a) ? a : {}, g[d] = n.extend(j, f, c)) : void 0 !== c && (g[d] = c));
            return g
        }, n.extend({
            expando: "jQuery" + (m + Math.random()).replace(/\D/g, ""),
            isReady: !0,
            error: function(a) {
                throw new Error(a)
            },
            noop: function() {},
            isFunction: function(a) {
                return "function" === n.type(a)
            },
            isArray: Array.isArray || function(a) {
                return "array" === n.type(a)
            },
            isWindow: function(a) {
                return null != a && a == a.window
            },
            isNumeric: function(a) {
                return a - parseFloat(a) >= 0
            },
            isEmptyObject: function(a) {
                var b;
                for (b in a) return !1;
                return !0
            },
            isPlainObject: function(a) {
                var b;
                if (!a || "object" !== n.type(a) || a.nodeType || n.isWindow(a)) return !1;
                try {
                    if (a.constructor && !j.call(a, "constructor") && !j.call(a.constructor.prototype, "isPrototypeOf")) return !1
                } catch (c) {
                    return !1
                }
                if (l.ownLast)
                    for (b in a) return j.call(a, b);
                for (b in a);
                return void 0 === b || j.call(a, b)
            },
            type: function(a) {
                return null == a ? a + "" : "object" == typeof a || "function" == typeof a ? h[i.call(a)] || "object" : typeof a
            },
            globalEval: function(b) {
                b && n.trim(b) && (a.execScript || function(b) {
                    a.eval.call(a, b)
                })(b)
            },
            camelCase: function(a) {
                return a.replace(p, "ms-").replace(q, r)
            },
            nodeName: function(a, b) {
                return a.nodeName && a.nodeName.toLowerCase() === b.toLowerCase()
            },
            each: function(a, b, c) {
                var d, e = 0,
                    f = a.length,
                    g = s(a);
                if (c) {
                    if (g) {
                        for (; f > e; e++)
                            if (d = b.apply(a[e], c), d === !1) break
                    } else
                        for (e in a)
                            if (d = b.apply(a[e], c), d === !1) break
                } else if (g) {
                    for (; f > e; e++)
                        if (d = b.call(a[e], e, a[e]), d === !1) break
                } else
                    for (e in a)
                        if (d = b.call(a[e], e, a[e]), d === !1) break;
                return a
            },
            trim: k && !k.call("\ufeff\xa0") ? function(a) {
                return null == a ? "" : k.call(a)
            } : function(a) {
                return null == a ? "" : (a + "").replace(o, "")
            },
            makeArray: function(a, b) {
                var c = b || [];
                return null != a && (s(Object(a)) ? n.merge(c, "string" == typeof a ? [a] : a) : f.call(c, a)), c
            },
            inArray: function(a, b, c) {
                var d;
                if (b) {
                    if (g) return g.call(b, a, c);
                    for (d = b.length, c = c ? 0 > c ? Math.max(0, d + c) : c : 0; d > c; c++)
                        if (c in b && b[c] === a) return c
                }
                return -1
            },
            merge: function(a, b) {
                var c = +b.length,
                    d = 0,
                    e = a.length;
                while (c > d) a[e++] = b[d++];
                if (c !== c)
                    while (void 0 !== b[d]) a[e++] = b[d++];
                return a.length = e, a
            },
            grep: function(a, b, c) {
                for (var d, e = [], f = 0, g = a.length, h = !c; g > f; f++) d = !b(a[f], f), d !== h && e.push(a[f]);
                return e
            },
            map: function(a, b, c) {
                var d, f = 0,
                    g = a.length,
                    h = s(a),
                    i = [];
                if (h)
                    for (; g > f; f++) d = b(a[f], f, c), null != d && i.push(d);
                else
                    for (f in a) d = b(a[f], f, c), null != d && i.push(d);
                return e.apply([], i)
            },
            guid: 1,
            proxy: function(a, b) {
                var c, e, f;
                return "string" == typeof b && (f = a[b], b = a, a = f), n.isFunction(a) ? (c = d.call(arguments, 2), e = function() {
                    return a.apply(b || this, c.concat(d.call(arguments)))
                }, e.guid = a.guid = a.guid || n.guid++, e) : void 0
            },
            now: function() {
                return +new Date
            },
            support: l
        }), n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(a, b) {
            h["[object " + b + "]"] = b.toLowerCase()
        });
    
        function s(a) {
            var b = a.length,
                c = n.type(a);
            return "function" === c || n.isWindow(a) ? !1 : 1 === a.nodeType && b ? !0 : "array" === c || 0 === b || "number" == typeof b && b > 0 && b - 1 in a
        }
        var t = function(a) {
            var b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s = "sizzle" + -new Date,
                t = a.document,
                u = 0,
                v = 0,
                w = eb(),
                x = eb(),
                y = eb(),
                z = function(a, b) {
                    return a === b && (j = !0), 0
                },
                A = "undefined",
                B = 1 << 31,
                C = {}.hasOwnProperty,
                D = [],
                E = D.pop,
                F = D.push,
                G = D.push,
                H = D.slice,
                I = D.indexOf || function(a) {
                    for (var b = 0, c = this.length; c > b; b++)
                        if (this[b] === a) return b;
                    return -1
                },
                J = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
                K = "[\\x20\\t\\r\\n\\f]",
                L = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
                M = L.replace("w", "w#"),
                N = "\\[" + K + "*(" + L + ")" + K + "*(?:([*^$|!~]?=)" + K + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + M + ")|)|)" + K + "*\\]",
                O = ":(" + L + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + N.replace(3, 8) + ")*)|.*)\\)|)",
                P = new RegExp("^" + K + "+|((?:^|[^\\\\])(?:\\\\.)*)" + K + "+$", "g"),
                Q = new RegExp("^" + K + "*," + K + "*"),
                R = new RegExp("^" + K + "*([>+~]|" + K + ")" + K + "*"),
                S = new RegExp("=" + K + "*([^\\]'\"]*?)" + K + "*\\]", "g"),
                T = new RegExp(O),
                U = new RegExp("^" + M + "$"),
                V = {
                    ID: new RegExp("^#(" + L + ")"),
                    CLASS: new RegExp("^\\.(" + L + ")"),
                    TAG: new RegExp("^(" + L.replace("w", "w*") + ")"),
                    ATTR: new RegExp("^" + N),
                    PSEUDO: new RegExp("^" + O),
                    CHILD: new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + K + "*(even|odd|(([+-]|)(\\d*)n|)" + K + "*(?:([+-]|)" + K + "*(\\d+)|))" + K + "*\\)|)", "i"),
                    bool: new RegExp("^(?:" + J + ")$", "i"),
                    needsContext: new RegExp("^" + K + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + K + "*((?:-\\d)?\\d*)" + K + "*\\)|)(?=[^-]|$)", "i")
                },
                W = /^(?:input|select|textarea|button)$/i,
                X = /^h\d$/i,
                Y = /^[^{]+\{\s*\[native \w/,
                Z = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
                $ = /[+~]/,
                _ = /'|\\/g,
                ab = new RegExp("\\\\([\\da-f]{1,6}" + K + "?|(" + K + ")|.)", "ig"),
                bb = function(a, b, c) {
                    var d = "0x" + b - 65536;
                    return d !== d || c ? b : 0 > d ? String.fromCharCode(d + 65536) : String.fromCharCode(d >> 10 | 55296, 1023 & d | 56320)
                };
            try {
                G.apply(D = H.call(t.childNodes), t.childNodes), D[t.childNodes.length].nodeType
            } catch (cb) {
                G = {
                    apply: D.length ? function(a, b) {
                        F.apply(a, H.call(b))
                    } : function(a, b) {
                        var c = a.length,
                            d = 0;
                        while (a[c++] = b[d++]);
                        a.length = c - 1
                    }
                }
            }
    
            function db(a, b, d, e) {
                var f, g, h, i, j, m, p, q, u, v;
                if ((b ? b.ownerDocument || b : t) !== l && k(b), b = b || l, d = d || [], !a || "string" != typeof a) return d;
                if (1 !== (i = b.nodeType) && 9 !== i) return [];
                if (n && !e) {
                    if (f = Z.exec(a))
                        if (h = f[1]) {
                            if (9 === i) {
                                if (g = b.getElementById(h), !g || !g.parentNode) return d;
                                if (g.id === h) return d.push(g), d
                            } else if (b.ownerDocument && (g = b.ownerDocument.getElementById(h)) && r(b, g) && g.id === h) return d.push(g), d
                        } else {
                            if (f[2]) return G.apply(d, b.getElementsByTagName(a)), d;
                            if ((h = f[3]) && c.getElementsByClassName && b.getElementsByClassName) return G.apply(d, b.getElementsByClassName(h)), d
                        }
                    if (c.qsa && (!o || !o.test(a))) {
                        if (q = p = s, u = b, v = 9 === i && a, 1 === i && "object" !== b.nodeName.toLowerCase()) {
                            m = ob(a), (p = b.getAttribute("id")) ? q = p.replace(_, "\\$&") : b.setAttribute("id", q), q = "[id='" + q + "'] ", j = m.length;
                            while (j--) m[j] = q + pb(m[j]);
                            u = $.test(a) && mb(b.parentNode) || b, v = m.join(",")
                        }
                        if (v) try {
                            return G.apply(d, u.querySelectorAll(v)), d
                        } catch (w) {} finally {
                            p || b.removeAttribute("id")
                        }
                    }
                }
                return xb(a.replace(P, "$1"), b, d, e)
            }
    
            function eb() {
                var a = [];
    
                function b(c, e) {
                    return a.push(c + " ") > d.cacheLength && delete b[a.shift()], b[c + " "] = e
                }
                return b
            }
    
            function fb(a) {
                return a[s] = !0, a
            }
    
            function gb(a) {
                var b = l.createElement("div");
                try {
                    return !!a(b)
                } catch (c) {
                    return !1
                } finally {
                    b.parentNode && b.parentNode.removeChild(b), b = null
                }
            }
    
            function hb(a, b) {
                var c = a.split("|"),
                    e = a.length;
                while (e--) d.attrHandle[c[e]] = b
            }
    
            function ib(a, b) {
                var c = b && a,
                    d = c && 1 === a.nodeType && 1 === b.nodeType && (~b.sourceIndex || B) - (~a.sourceIndex || B);
                if (d) return d;
                if (c)
                    while (c = c.nextSibling)
                        if (c === b) return -1;
                return a ? 1 : -1
            }
    
            function jb(a) {
                return function(b) {
                    var c = b.nodeName.toLowerCase();
                    return "input" === c && b.type === a
                }
            }
    
            function kb(a) {
                return function(b) {
                    var c = b.nodeName.toLowerCase();
                    return ("input" === c || "button" === c) && b.type === a
                }
            }
    
            function lb(a) {
                return fb(function(b) {
                    return b = +b, fb(function(c, d) {
                        var e, f = a([], c.length, b),
                            g = f.length;
                        while (g--) c[e = f[g]] && (c[e] = !(d[e] = c[e]))
                    })
                })
            }
    
            function mb(a) {
                return a && typeof a.getElementsByTagName !== A && a
            }
            c = db.support = {}, f = db.isXML = function(a) {
                var b = a && (a.ownerDocument || a).documentElement;
                return b ? "HTML" !== b.nodeName : !1
            }, k = db.setDocument = function(a) {
                var b, e = a ? a.ownerDocument || a : t,
                    g = e.defaultView;
                return e !== l && 9 === e.nodeType && e.documentElement ? (l = e, m = e.documentElement, n = !f(e), g && g !== g.top && (g.addEventListener ? g.addEventListener("unload", function() {
                    k()
                }, !1) : g.attachEvent && g.attachEvent("onunload", function() {
                    k()
                })), c.attributes = gb(function(a) {
                    return a.className = "i", !a.getAttribute("className")
                }), c.getElementsByTagName = gb(function(a) {
                    return a.appendChild(e.createComment("")), !a.getElementsByTagName("*").length
                }), c.getElementsByClassName = Y.test(e.getElementsByClassName) && gb(function(a) {
                    return a.innerHTML = "<div class='a'></div><div class='a i'></div>", a.firstChild.className = "i", 2 === a.getElementsByClassName("i").length
                }), c.getById = gb(function(a) {
                    return m.appendChild(a).id = s, !e.getElementsByName || !e.getElementsByName(s).length
                }), c.getById ? (d.find.ID = function(a, b) {
                    if (typeof b.getElementById !== A && n) {
                        var c = b.getElementById(a);
                        return c && c.parentNode ? [c] : []
                    }
                }, d.filter.ID = function(a) {
                    var b = a.replace(ab, bb);
                    return function(a) {
                        return a.getAttribute("id") === b
                    }
                }) : (delete d.find.ID, d.filter.ID = function(a) {
                    var b = a.replace(ab, bb);
                    return function(a) {
                        var c = typeof a.getAttributeNode !== A && a.getAttributeNode("id");
                        return c && c.value === b
                    }
                }), d.find.TAG = c.getElementsByTagName ? function(a, b) {
                    return typeof b.getElementsByTagName !== A ? b.getElementsByTagName(a) : void 0
                } : function(a, b) {
                    var c, d = [],
                        e = 0,
                        f = b.getElementsByTagName(a);
                    if ("*" === a) {
                        while (c = f[e++]) 1 === c.nodeType && d.push(c);
                        return d
                    }
                    return f
                }, d.find.CLASS = c.getElementsByClassName && function(a, b) {
                    return typeof b.getElementsByClassName !== A && n ? b.getElementsByClassName(a) : void 0
                }, p = [], o = [], (c.qsa = Y.test(e.querySelectorAll)) && (gb(function(a) {
                    a.innerHTML = "<select t=''><option selected=''></option></select>", a.querySelectorAll("[t^='']").length && o.push("[*^$]=" + K + "*(?:''|\"\")"), a.querySelectorAll("[selected]").length || o.push("\\[" + K + "*(?:value|" + J + ")"), a.querySelectorAll(":checked").length || o.push(":checked")
                }), gb(function(a) {
                    var b = e.createElement("input");
                    b.setAttribute("type", "hidden"), a.appendChild(b).setAttribute("name", "D"), a.querySelectorAll("[name=d]").length && o.push("name" + K + "*[*^$|!~]?="), a.querySelectorAll(":enabled").length || o.push(":enabled", ":disabled"), a.querySelectorAll("*,:x"), o.push(",.*:")
                })), (c.matchesSelector = Y.test(q = m.webkitMatchesSelector || m.mozMatchesSelector || m.oMatchesSelector || m.msMatchesSelector)) && gb(function(a) {
                    c.disconnectedMatch = q.call(a, "div"), q.call(a, "[s!='']:x"), p.push("!=", O)
                }), o = o.length && new RegExp(o.join("|")), p = p.length && new RegExp(p.join("|")), b = Y.test(m.compareDocumentPosition), r = b || Y.test(m.contains) ? function(a, b) {
                    var c = 9 === a.nodeType ? a.documentElement : a,
                        d = b && b.parentNode;
                    return a === d || !(!d || 1 !== d.nodeType || !(c.contains ? c.contains(d) : a.compareDocumentPosition && 16 & a.compareDocumentPosition(d)))
                } : function(a, b) {
                    if (b)
                        while (b = b.parentNode)
                            if (b === a) return !0;
                    return !1
                }, z = b ? function(a, b) {
                    if (a === b) return j = !0, 0;
                    var d = !a.compareDocumentPosition - !b.compareDocumentPosition;
                    return d ? d : (d = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1, 1 & d || !c.sortDetached && b.compareDocumentPosition(a) === d ? a === e || a.ownerDocument === t && r(t, a) ? -1 : b === e || b.ownerDocument === t && r(t, b) ? 1 : i ? I.call(i, a) - I.call(i, b) : 0 : 4 & d ? -1 : 1)
                } : function(a, b) {
                    if (a === b) return j = !0, 0;
                    var c, d = 0,
                        f = a.parentNode,
                        g = b.parentNode,
                        h = [a],
                        k = [b];
                    if (!f || !g) return a === e ? -1 : b === e ? 1 : f ? -1 : g ? 1 : i ? I.call(i, a) - I.call(i, b) : 0;
                    if (f === g) return ib(a, b);
                    c = a;
                    while (c = c.parentNode) h.unshift(c);
                    c = b;
                    while (c = c.parentNode) k.unshift(c);
                    while (h[d] === k[d]) d++;
                    return d ? ib(h[d], k[d]) : h[d] === t ? -1 : k[d] === t ? 1 : 0
                }, e) : l
            }, db.matches = function(a, b) {
                return db(a, null, null, b)
            }, db.matchesSelector = function(a, b) {
                if ((a.ownerDocument || a) !== l && k(a), b = b.replace(S, "='$1']"), !(!c.matchesSelector || !n || p && p.test(b) || o && o.test(b))) try {
                    var d = q.call(a, b);
                    if (d || c.disconnectedMatch || a.document && 11 !== a.document.nodeType) return d
                } catch (e) {}
                return db(b, l, null, [a]).length > 0
            }, db.contains = function(a, b) {
                return (a.ownerDocument || a) !== l && k(a), r(a, b)
            }, db.attr = function(a, b) {
                (a.ownerDocument || a) !== l && k(a);
                var e = d.attrHandle[b.toLowerCase()],
                    f = e && C.call(d.attrHandle, b.toLowerCase()) ? e(a, b, !n) : void 0;
                return void 0 !== f ? f : c.attributes || !n ? a.getAttribute(b) : (f = a.getAttributeNode(b)) && f.specified ? f.value : null
            }, db.error = function(a) {
                throw new Error("Syntax error, unrecognized expression: " + a)
            }, db.uniqueSort = function(a) {
                var b, d = [],
                    e = 0,
                    f = 0;
                if (j = !c.detectDuplicates, i = !c.sortStable && a.slice(0), a.sort(z), j) {
                    while (b = a[f++]) b === a[f] && (e = d.push(f));
                    while (e--) a.splice(d[e], 1)
                }
                return i = null, a
            }, e = db.getText = function(a) {
                var b, c = "",
                    d = 0,
                    f = a.nodeType;
                if (f) {
                    if (1 === f || 9 === f || 11 === f) {
                        if ("string" == typeof a.textContent) return a.textContent;
                        for (a = a.firstChild; a; a = a.nextSibling) c += e(a)
                    } else if (3 === f || 4 === f) return a.nodeValue
                } else
                    while (b = a[d++]) c += e(b);
                return c
            }, d = db.selectors = {
                cacheLength: 50,
                createPseudo: fb,
                match: V,
                attrHandle: {},
                find: {},
                relative: {
                    ">": {
                        dir: "parentNode",
                        first: !0
                    },
                    " ": {
                        dir: "parentNode"
                    },
                    "+": {
                        dir: "previousSibling",
                        first: !0
                    },
                    "~": {
                        dir: "previousSibling"
                    }
                },
                preFilter: {
                    ATTR: function(a) {
                        return a[1] = a[1].replace(ab, bb), a[3] = (a[4] || a[5] || "").replace(ab, bb), "~=" === a[2] && (a[3] = " " + a[3] + " "), a.slice(0, 4)
                    },
                    CHILD: function(a) {
                        return a[1] = a[1].toLowerCase(), "nth" === a[1].slice(0, 3) ? (a[3] || db.error(a[0]), a[4] = +(a[4] ? a[5] + (a[6] || 1) : 2 * ("even" === a[3] || "odd" === a[3])), a[5] = +(a[7] + a[8] || "odd" === a[3])) : a[3] && db.error(a[0]), a
                    },
                    PSEUDO: function(a) {
                        var b, c = !a[5] && a[2];
                        return V.CHILD.test(a[0]) ? null : (a[3] && void 0 !== a[4] ? a[2] = a[4] : c && T.test(c) && (b = ob(c, !0)) && (b = c.indexOf(")", c.length - b) - c.length) && (a[0] = a[0].slice(0, b), a[2] = c.slice(0, b)), a.slice(0, 3))
                    }
                },
                filter: {
                    TAG: function(a) {
                        var b = a.replace(ab, bb).toLowerCase();
                        return "*" === a ? function() {
                            return !0
                        } : function(a) {
                            return a.nodeName && a.nodeName.toLowerCase() === b
                        }
                    },
                    CLASS: function(a) {
                        var b = w[a + " "];
                        return b || (b = new RegExp("(^|" + K + ")" + a + "(" + K + "|$)")) && w(a, function(a) {
                            return b.test("string" == typeof a.className && a.className || typeof a.getAttribute !== A && a.getAttribute("class") || "")
                        })
                    },
                    ATTR: function(a, b, c) {
                        return function(d) {
                            var e = db.attr(d, a);
                            return null == e ? "!=" === b : b ? (e += "", "=" === b ? e === c : "!=" === b ? e !== c : "^=" === b ? c && 0 === e.indexOf(c) : "*=" === b ? c && e.indexOf(c) > -1 : "$=" === b ? c && e.slice(-c.length) === c : "~=" === b ? (" " + e + " ").indexOf(c) > -1 : "|=" === b ? e === c || e.slice(0, c.length + 1) === c + "-" : !1) : !0
                        }
                    },
                    CHILD: function(a, b, c, d, e) {
                        var f = "nth" !== a.slice(0, 3),
                            g = "last" !== a.slice(-4),
                            h = "of-type" === b;
                        return 1 === d && 0 === e ? function(a) {
                            return !!a.parentNode
                        } : function(b, c, i) {
                            var j, k, l, m, n, o, p = f !== g ? "nextSibling" : "previousSibling",
                                q = b.parentNode,
                                r = h && b.nodeName.toLowerCase(),
                                t = !i && !h;
                            if (q) {
                                if (f) {
                                    while (p) {
                                        l = b;
                                        while (l = l[p])
                                            if (h ? l.nodeName.toLowerCase() === r : 1 === l.nodeType) return !1;
                                        o = p = "only" === a && !o && "nextSibling"
                                    }
                                    return !0
                                }
                                if (o = [g ? q.firstChild : q.lastChild], g && t) {
                                    k = q[s] || (q[s] = {}), j = k[a] || [], n = j[0] === u && j[1], m = j[0] === u && j[2], l = n && q.childNodes[n];
                                    while (l = ++n && l && l[p] || (m = n = 0) || o.pop())
                                        if (1 === l.nodeType && ++m && l === b) {
                                            k[a] = [u, n, m];
                                            break
                                        }
                                } else if (t && (j = (b[s] || (b[s] = {}))[a]) && j[0] === u) m = j[1];
                                else
                                    while (l = ++n && l && l[p] || (m = n = 0) || o.pop())
                                        if ((h ? l.nodeName.toLowerCase() === r : 1 === l.nodeType) && ++m && (t && ((l[s] || (l[s] = {}))[a] = [u, m]), l === b)) break;
                                return m -= e, m === d || m % d === 0 && m / d >= 0
                            }
                        }
                    },
                    PSEUDO: function(a, b) {
                        var c, e = d.pseudos[a] || d.setFilters[a.toLowerCase()] || db.error("unsupported pseudo: " + a);
                        return e[s] ? e(b) : e.length > 1 ? (c = [a, a, "", b], d.setFilters.hasOwnProperty(a.toLowerCase()) ? fb(function(a, c) {
                            var d, f = e(a, b),
                                g = f.length;
                            while (g--) d = I.call(a, f[g]), a[d] = !(c[d] = f[g])
                        }) : function(a) {
                            return e(a, 0, c)
                        }) : e
                    }
                },
                pseudos: {
                    not: fb(function(a) {
                        var b = [],
                            c = [],
                            d = g(a.replace(P, "$1"));
                        return d[s] ? fb(function(a, b, c, e) {
                            var f, g = d(a, null, e, []),
                                h = a.length;
                            while (h--)(f = g[h]) && (a[h] = !(b[h] = f))
                        }) : function(a, e, f) {
                            return b[0] = a, d(b, null, f, c), !c.pop()
                        }
                    }),
                    has: fb(function(a) {
                        return function(b) {
                            return db(a, b).length > 0
                        }
                    }),
                    contains: fb(function(a) {
                        return function(b) {
                            return (b.textContent || b.innerText || e(b)).indexOf(a) > -1
                        }
                    }),
                    lang: fb(function(a) {
                        return U.test(a || "") || db.error("unsupported lang: " + a), a = a.replace(ab, bb).toLowerCase(),
                            function(b) {
                                var c;
                                do
                                    if (c = n ? b.lang : b.getAttribute("xml:lang") || b.getAttribute("lang")) return c = c.toLowerCase(), c === a || 0 === c.indexOf(a + "-"); while ((b = b.parentNode) && 1 === b.nodeType);
                                return !1
                            }
                    }),
                    target: function(b) {
                        var c = a.location && a.location.hash;
                        return c && c.slice(1) === b.id
                    },
                    root: function(a) {
                        return a === m
                    },
                    focus: function(a) {
                        return a === l.activeElement && (!l.hasFocus || l.hasFocus()) && !!(a.type || a.href || ~a.tabIndex)
                    },
                    enabled: function(a) {
                        return a.disabled === !1
                    },
                    disabled: function(a) {
                        return a.disabled === !0
                    },
                    checked: function(a) {
                        var b = a.nodeName.toLowerCase();
                        return "input" === b && !!a.checked || "option" === b && !!a.selected
                    },
                    selected: function(a) {
                        return a.parentNode && a.parentNode.selectedIndex, a.selected === !0
                    },
                    empty: function(a) {
                        for (a = a.firstChild; a; a = a.nextSibling)
                            if (a.nodeType < 6) return !1;
                        return !0
                    },
                    parent: function(a) {
                        return !d.pseudos.empty(a)
                    },
                    header: function(a) {
                        return X.test(a.nodeName)
                    },
                    input: function(a) {
                        return W.test(a.nodeName)
                    },
                    button: function(a) {
                        var b = a.nodeName.toLowerCase();
                        return "input" === b && "button" === a.type || "button" === b
                    },
                    text: function(a) {
                        var b;
                        return "input" === a.nodeName.toLowerCase() && "text" === a.type && (null == (b = a.getAttribute("type")) || "text" === b.toLowerCase())
                    },
                    first: lb(function() {
                        return [0]
                    }),
                    last: lb(function(a, b) {
                        return [b - 1]
                    }),
                    eq: lb(function(a, b, c) {
                        return [0 > c ? c + b : c]
                    }),
                    even: lb(function(a, b) {
                        for (var c = 0; b > c; c += 2) a.push(c);
                        return a
                    }),
                    odd: lb(function(a, b) {
                        for (var c = 1; b > c; c += 2) a.push(c);
                        return a
                    }),
                    lt: lb(function(a, b, c) {
                        for (var d = 0 > c ? c + b : c; --d >= 0;) a.push(d);
                        return a
                    }),
                    gt: lb(function(a, b, c) {
                        for (var d = 0 > c ? c + b : c; ++d < b;) a.push(d);
                        return a
                    })
                }
            }, d.pseudos.nth = d.pseudos.eq;
            for (b in {
                    radio: !0,
                    checkbox: !0,
                    file: !0,
                    password: !0,
                    image: !0
                }) d.pseudos[b] = jb(b);
            for (b in {
                    submit: !0,
                    reset: !0
                }) d.pseudos[b] = kb(b);
    
            function nb() {}
            nb.prototype = d.filters = d.pseudos, d.setFilters = new nb;
    
            function ob(a, b) {
                var c, e, f, g, h, i, j, k = x[a + " "];
                if (k) return b ? 0 : k.slice(0);
                h = a, i = [], j = d.preFilter;
                while (h) {
                    (!c || (e = Q.exec(h))) && (e && (h = h.slice(e[0].length) || h), i.push(f = [])), c = !1, (e = R.exec(h)) && (c = e.shift(), f.push({
                        value: c,
                        type: e[0].replace(P, " ")
                    }), h = h.slice(c.length));
                    for (g in d.filter) !(e = V[g].exec(h)) || j[g] && !(e = j[g](e)) || (c = e.shift(), f.push({
                        value: c,
                        type: g,
                        matches: e
                    }), h = h.slice(c.length));
                    if (!c) break
                }
                return b ? h.length : h ? db.error(a) : x(a, i).slice(0)
            }
    
            function pb(a) {
                for (var b = 0, c = a.length, d = ""; c > b; b++) d += a[b].value;
                return d
            }
    
            function qb(a, b, c) {
                var d = b.dir,
                    e = c && "parentNode" === d,
                    f = v++;
                return b.first ? function(b, c, f) {
                    while (b = b[d])
                        if (1 === b.nodeType || e) return a(b, c, f)
                } : function(b, c, g) {
                    var h, i, j = [u, f];
                    if (g) {
                        while (b = b[d])
                            if ((1 === b.nodeType || e) && a(b, c, g)) return !0
                    } else
                        while (b = b[d])
                            if (1 === b.nodeType || e) {
                                if (i = b[s] || (b[s] = {}), (h = i[d]) && h[0] === u && h[1] === f) return j[2] = h[2];
                                if (i[d] = j, j[2] = a(b, c, g)) return !0
                            }
                }
            }
    
            function rb(a) {
                return a.length > 1 ? function(b, c, d) {
                    var e = a.length;
                    while (e--)
                        if (!a[e](b, c, d)) return !1;
                    return !0
                } : a[0]
            }
    
            function sb(a, b, c, d, e) {
                for (var f, g = [], h = 0, i = a.length, j = null != b; i > h; h++)(f = a[h]) && (!c || c(f, d, e)) && (g.push(f), j && b.push(h));
                return g
            }
    
            function tb(a, b, c, d, e, f) {
                return d && !d[s] && (d = tb(d)), e && !e[s] && (e = tb(e, f)), fb(function(f, g, h, i) {
                    var j, k, l, m = [],
                        n = [],
                        o = g.length,
                        p = f || wb(b || "*", h.nodeType ? [h] : h, []),
                        q = !a || !f && b ? p : sb(p, m, a, h, i),
                        r = c ? e || (f ? a : o || d) ? [] : g : q;
                    if (c && c(q, r, h, i), d) {
                        j = sb(r, n), d(j, [], h, i), k = j.length;
                        while (k--)(l = j[k]) && (r[n[k]] = !(q[n[k]] = l))
                    }
                    if (f) {
                        if (e || a) {
                            if (e) {
                                j = [], k = r.length;
                                while (k--)(l = r[k]) && j.push(q[k] = l);
                                e(null, r = [], j, i)
                            }
                            k = r.length;
                            while (k--)(l = r[k]) && (j = e ? I.call(f, l) : m[k]) > -1 && (f[j] = !(g[j] = l))
                        }
                    } else r = sb(r === g ? r.splice(o, r.length) : r), e ? e(null, g, r, i) : G.apply(g, r)
                })
            }
    
            function ub(a) {
                for (var b, c, e, f = a.length, g = d.relative[a[0].type], i = g || d.relative[" "], j = g ? 1 : 0, k = qb(function(a) {
                        return a === b
                    }, i, !0), l = qb(function(a) {
                        return I.call(b, a) > -1
                    }, i, !0), m = [function(a, c, d) {
                        return !g && (d || c !== h) || ((b = c).nodeType ? k(a, c, d) : l(a, c, d))
                    }]; f > j; j++)
                    if (c = d.relative[a[j].type]) m = [qb(rb(m), c)];
                    else {
                        if (c = d.filter[a[j].type].apply(null, a[j].matches), c[s]) {
                            for (e = ++j; f > e; e++)
                                if (d.relative[a[e].type]) break;
                            return tb(j > 1 && rb(m), j > 1 && pb(a.slice(0, j - 1).concat({
                                value: " " === a[j - 2].type ? "*" : ""
                            })).replace(P, "$1"), c, e > j && ub(a.slice(j, e)), f > e && ub(a = a.slice(e)), f > e && pb(a))
                        }
                        m.push(c)
                    }
                return rb(m)
            }
    
            function vb(a, b) {
                var c = b.length > 0,
                    e = a.length > 0,
                    f = function(f, g, i, j, k) {
                        var m, n, o, p = 0,
                            q = "0",
                            r = f && [],
                            s = [],
                            t = h,
                            v = f || e && d.find.TAG("*", k),
                            w = u += null == t ? 1 : Math.random() || .1,
                            x = v.length;
                        for (k && (h = g !== l && g); q !== x && null != (m = v[q]); q++) {
                            if (e && m) {
                                n = 0;
                                while (o = a[n++])
                                    if (o(m, g, i)) {
                                        j.push(m);
                                        break
                                    }
                                k && (u = w)
                            }
                            c && ((m = !o && m) && p--, f && r.push(m))
                        }
                        if (p += q, c && q !== p) {
                            n = 0;
                            while (o = b[n++]) o(r, s, g, i);
                            if (f) {
                                if (p > 0)
                                    while (q--) r[q] || s[q] || (s[q] = E.call(j));
                                s = sb(s)
                            }
                            G.apply(j, s), k && !f && s.length > 0 && p + b.length > 1 && db.uniqueSort(j)
                        }
                        return k && (u = w, h = t), r
                    };
                return c ? fb(f) : f
            }
            g = db.compile = function(a, b) {
                var c, d = [],
                    e = [],
                    f = y[a + " "];
                if (!f) {
                    b || (b = ob(a)), c = b.length;
                    while (c--) f = ub(b[c]), f[s] ? d.push(f) : e.push(f);
                    f = y(a, vb(e, d))
                }
                return f
            };
    
            function wb(a, b, c) {
                for (var d = 0, e = b.length; e > d; d++) db(a, b[d], c);
                return c
            }
    
            function xb(a, b, e, f) {
                var h, i, j, k, l, m = ob(a);
                if (!f && 1 === m.length) {
                    if (i = m[0] = m[0].slice(0), i.length > 2 && "ID" === (j = i[0]).type && c.getById && 9 === b.nodeType && n && d.relative[i[1].type]) {
                        if (b = (d.find.ID(j.matches[0].replace(ab, bb), b) || [])[0], !b) return e;
                        a = a.slice(i.shift().value.length)
                    }
                    h = V.needsContext.test(a) ? 0 : i.length;
                    while (h--) {
                        if (j = i[h], d.relative[k = j.type]) break;
                        if ((l = d.find[k]) && (f = l(j.matches[0].replace(ab, bb), $.test(i[0].type) && mb(b.parentNode) || b))) {
                            if (i.splice(h, 1), a = f.length && pb(i), !a) return G.apply(e, f), e;
                            break
                        }
                    }
                }
                return g(a, m)(f, b, !n, e, $.test(a) && mb(b.parentNode) || b), e
            }
            return c.sortStable = s.split("").sort(z).join("") === s, c.detectDuplicates = !!j, k(), c.sortDetached = gb(function(a) {
                return 1 & a.compareDocumentPosition(l.createElement("div"))
            }), gb(function(a) {
                return a.innerHTML = "<a href='#'></a>", "#" === a.firstChild.getAttribute("href")
            }) || hb("type|href|height|width", function(a, b, c) {
                return c ? void 0 : a.getAttribute(b, "type" === b.toLowerCase() ? 1 : 2)
            }), c.attributes && gb(function(a) {
                return a.innerHTML = "<input/>", a.firstChild.setAttribute("value", ""), "" === a.firstChild.getAttribute("value")
            }) || hb("value", function(a, b, c) {
                return c || "input" !== a.nodeName.toLowerCase() ? void 0 : a.defaultValue
            }), gb(function(a) {
                return null == a.getAttribute("disabled")
            }) || hb(J, function(a, b, c) {
                var d;
                return c ? void 0 : a[b] === !0 ? b.toLowerCase() : (d = a.getAttributeNode(b)) && d.specified ? d.value : null
            }), db
        }(a);
        n.find = t, n.expr = t.selectors, n.expr[":"] = n.expr.pseudos, n.unique = t.uniqueSort, n.text = t.getText, n.isXMLDoc = t.isXML, n.contains = t.contains;
        var u = n.expr.match.needsContext,
            v = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
            w = /^.[^:#\[\.,]*$/;
    
        function x(a, b, c) {
            if (n.isFunction(b)) return n.grep(a, function(a, d) {
                return !!b.call(a, d, a) !== c
            });
            if (b.nodeType) return n.grep(a, function(a) {
                return a === b !== c
            });
            if ("string" == typeof b) {
                if (w.test(b)) return n.filter(b, a, c);
                b = n.filter(b, a)
            }
            return n.grep(a, function(a) {
                return n.inArray(a, b) >= 0 !== c
            })
        }
        n.filter = function(a, b, c) {
            var d = b[0];
            return c && (a = ":not(" + a + ")"), 1 === b.length && 1 === d.nodeType ? n.find.matchesSelector(d, a) ? [d] : [] : n.find.matches(a, n.grep(b, function(a) {
                return 1 === a.nodeType
            }))
        }, n.fn.extend({
            find: function(a) {
                var b, c = [],
                    d = this,
                    e = d.length;
                if ("string" != typeof a) return this.pushStack(n(a).filter(function() {
                    for (b = 0; e > b; b++)
                        if (n.contains(d[b], this)) return !0
                }));
                for (b = 0; e > b; b++) n.find(a, d[b], c);
                return c = this.pushStack(e > 1 ? n.unique(c) : c), c.selector = this.selector ? this.selector + " " + a : a, c
            },
            filter: function(a) {
                return this.pushStack(x(this, a || [], !1))
            },
            not: function(a) {
                return this.pushStack(x(this, a || [], !0))
            },
            is: function(a) {
                return !!x(this, "string" == typeof a && u.test(a) ? n(a) : a || [], !1).length
            }
        });
        var y, z = a.document,
            A = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
            B = n.fn.init = function(a, b) {
                var c, d;
                if (!a) return this;
                if ("string" == typeof a) {
                    if (c = "<" === a.charAt(0) && ">" === a.charAt(a.length - 1) && a.length >= 3 ? [null, a, null] : A.exec(a), !c || !c[1] && b) return !b || b.jquery ? (b || y).find(a) : this.constructor(b).find(a);
                    if (c[1]) {
                        if (b = b instanceof n ? b[0] : b, n.merge(this, n.parseHTML(c[1], b && b.nodeType ? b.ownerDocument || b : z, !0)), v.test(c[1]) && n.isPlainObject(b))
                            for (c in b) n.isFunction(this[c]) ? this[c](b[c]) : this.attr(c, b[c]);
                        return this
                    }
                    if (d = z.getElementById(c[2]), d && d.parentNode) {
                        if (d.id !== c[2]) return y.find(a);
                        this.length = 1, this[0] = d
                    }
                    return this.context = z, this.selector = a, this
                }
                return a.nodeType ? (this.context = this[0] = a, this.length = 1, this) : n.isFunction(a) ? "undefined" != typeof y.ready ? y.ready(a) : a(n) : (void 0 !== a.selector && (this.selector = a.selector, this.context = a.context), n.makeArray(a, this))
            };
        B.prototype = n.fn, y = n(z);
        var C = /^(?:parents|prev(?:Until|All))/,
            D = {
                children: !0,
                contents: !0,
                next: !0,
                prev: !0
            };
        n.extend({
            dir: function(a, b, c) {
                var d = [],
                    e = a[b];
                while (e && 9 !== e.nodeType && (void 0 === c || 1 !== e.nodeType || !n(e).is(c))) 1 === e.nodeType && d.push(e), e = e[b];
                return d
            },
            sibling: function(a, b) {
                for (var c = []; a; a = a.nextSibling) 1 === a.nodeType && a !== b && c.push(a);
                return c
            }
        }), n.fn.extend({
            has: function(a) {
                var b, c = n(a, this),
                    d = c.length;
                return this.filter(function() {
                    for (b = 0; d > b; b++)
                        if (n.contains(this, c[b])) return !0
                })
            },
            closest: function(a, b) {
                for (var c, d = 0, e = this.length, f = [], g = u.test(a) || "string" != typeof a ? n(a, b || this.context) : 0; e > d; d++)
                    for (c = this[d]; c && c !== b; c = c.parentNode)
                        if (c.nodeType < 11 && (g ? g.index(c) > -1 : 1 === c.nodeType && n.find.matchesSelector(c, a))) {
                            f.push(c);
                            break
                        }
                return this.pushStack(f.length > 1 ? n.unique(f) : f)
            },
            index: function(a) {
                return a ? "string" == typeof a ? n.inArray(this[0], n(a)) : n.inArray(a.jquery ? a[0] : a, this) : this[0] && this[0].parentNode ? this.first().prevAll().length : -1
            },
            add: function(a, b) {
                return this.pushStack(n.unique(n.merge(this.get(), n(a, b))))
            },
            addBack: function(a) {
                return this.add(null == a ? this.prevObject : this.prevObject.filter(a))
            }
        });
    
        function E(a, b) {
            do a = a[b]; while (a && 1 !== a.nodeType);
            return a
        }
        n.each({
            parent: function(a) {
                var b = a.parentNode;
                return b && 11 !== b.nodeType ? b : null
            },
            parents: function(a) {
                return n.dir(a, "parentNode")
            },
            parentsUntil: function(a, b, c) {
                return n.dir(a, "parentNode", c)
            },
            next: function(a) {
                return E(a, "nextSibling")
            },
            prev: function(a) {
                return E(a, "previousSibling")
            },
            nextAll: function(a) {
                return n.dir(a, "nextSibling")
            },
            prevAll: function(a) {
                return n.dir(a, "previousSibling")
            },
            nextUntil: function(a, b, c) {
                return n.dir(a, "nextSibling", c)
            },
            prevUntil: function(a, b, c) {
                return n.dir(a, "previousSibling", c)
            },
            siblings: function(a) {
                return n.sibling((a.parentNode || {}).firstChild, a)
            },
            children: function(a) {
                return n.sibling(a.firstChild)
            },
            contents: function(a) {
                return n.nodeName(a, "iframe") ? a.contentDocument || a.contentWindow.document : n.merge([], a.childNodes)
            }
        }, function(a, b) {
            n.fn[a] = function(c, d) {
                var e = n.map(this, b, c);
                return "Until" !== a.slice(-5) && (d = c), d && "string" == typeof d && (e = n.filter(d, e)), this.length > 1 && (D[a] || (e = n.unique(e)), C.test(a) && (e = e.reverse())), this.pushStack(e)
            }
        });
        var F = /\S+/g,
            G = {};
    
        function H(a) {
            var b = G[a] = {};
            return n.each(a.match(F) || [], function(a, c) {
                b[c] = !0
            }), b
        }
        n.Callbacks = function(a) {
            a = "string" == typeof a ? G[a] || H(a) : n.extend({}, a);
            var b, c, d, e, f, g, h = [],
                i = !a.once && [],
                j = function(l) {
                    for (c = a.memory && l, d = !0, f = g || 0, g = 0, e = h.length, b = !0; h && e > f; f++)
                        if (h[f].apply(l[0], l[1]) === !1 && a.stopOnFalse) {
                            c = !1;
                            break
                        }
                    b = !1, h && (i ? i.length && j(i.shift()) : c ? h = [] : k.disable())
                },
                k = {
                    add: function() {
                        if (h) {
                            var d = h.length;
                            ! function f(b) {
                                n.each(b, function(b, c) {
                                    var d = n.type(c);
                                    "function" === d ? a.unique && k.has(c) || h.push(c) : c && c.length && "string" !== d && f(c)
                                })
                            }(arguments), b ? e = h.length : c && (g = d, j(c))
                        }
                        return this
                    },
                    remove: function() {
                        return h && n.each(arguments, function(a, c) {
                            var d;
                            while ((d = n.inArray(c, h, d)) > -1) h.splice(d, 1), b && (e >= d && e--, f >= d && f--)
                        }), this
                    },
                    has: function(a) {
                        return a ? n.inArray(a, h) > -1 : !(!h || !h.length)
                    },
                    empty: function() {
                        return h = [], e = 0, this
                    },
                    disable: function() {
                        return h = i = c = void 0, this
                    },
                    disabled: function() {
                        return !h
                    },
                    lock: function() {
                        return i = void 0, c || k.disable(), this
                    },
                    locked: function() {
                        return !i
                    },
                    fireWith: function(a, c) {
                        return !h || d && !i || (c = c || [], c = [a, c.slice ? c.slice() : c], b ? i.push(c) : j(c)), this
                    },
                    fire: function() {
                        return k.fireWith(this, arguments), this
                    },
                    fired: function() {
                        return !!d
                    }
                };
            return k
        }, n.extend({
            Deferred: function(a) {
                var b = [
                        ["resolve", "done", n.Callbacks("once memory"), "resolved"],
                        ["reject", "fail", n.Callbacks("once memory"), "rejected"],
                        ["notify", "progress", n.Callbacks("memory")]
                    ],
                    c = "pending",
                    d = {
                        state: function() {
                            return c
                        },
                        always: function() {
                            return e.done(arguments).fail(arguments), this
                        },
                        then: function() {
                            var a = arguments;
                            return n.Deferred(function(c) {
                                n.each(b, function(b, f) {
                                    var g = n.isFunction(a[b]) && a[b];
                                    e[f[1]](function() {
                                        var a = g && g.apply(this, arguments);
                                        a && n.isFunction(a.promise) ? a.promise().done(c.resolve).fail(c.reject).progress(c.notify) : c[f[0] + "With"](this === d ? c.promise() : this, g ? [a] : arguments)
                                    })
                                }), a = null
                            }).promise()
                        },
                        promise: function(a) {
                            return null != a ? n.extend(a, d) : d
                        }
                    },
                    e = {};
                return d.pipe = d.then, n.each(b, function(a, f) {
                    var g = f[2],
                        h = f[3];
                    d[f[1]] = g.add, h && g.add(function() {
                        c = h
                    }, b[1 ^ a][2].disable, b[2][2].lock), e[f[0]] = function() {
                        return e[f[0] + "With"](this === e ? d : this, arguments), this
                    }, e[f[0] + "With"] = g.fireWith
                }), d.promise(e), a && a.call(e, e), e
            },
            when: function(a) {
                var b = 0,
                    c = d.call(arguments),
                    e = c.length,
                    f = 1 !== e || a && n.isFunction(a.promise) ? e : 0,
                    g = 1 === f ? a : n.Deferred(),
                    h = function(a, b, c) {
                        return function(e) {
                            b[a] = this, c[a] = arguments.length > 1 ? d.call(arguments) : e, c === i ? g.notifyWith(b, c) : --f || g.resolveWith(b, c)
                        }
                    },
                    i, j, k;
                if (e > 1)
                    for (i = new Array(e), j = new Array(e), k = new Array(e); e > b; b++) c[b] && n.isFunction(c[b].promise) ? c[b].promise().done(h(b, k, c)).fail(g.reject).progress(h(b, j, i)) : --f;
                return f || g.resolveWith(k, c), g.promise()
            }
        });
        var I;
        n.fn.ready = function(a) {
            return n.ready.promise().done(a), this
        }, n.extend({
            isReady: !1,
            readyWait: 1,
            holdReady: function(a) {
                a ? n.readyWait++ : n.ready(!0)
            },
            ready: function(a) {
                if (a === !0 ? !--n.readyWait : !n.isReady) {
                    if (!z.body) return setTimeout(n.ready);
                    n.isReady = !0, a !== !0 && --n.readyWait > 0 || (I.resolveWith(z, [n]), n.fn.trigger && n(z).trigger("ready").off("ready"))
                }
            }
        });
    
        function J() {
            z.addEventListener ? (z.removeEventListener("DOMContentLoaded", K, !1), a.removeEventListener("load", K, !1)) : (z.detachEvent("onreadystatechange", K), a.detachEvent("onload", K))
        }
    
        function K() {
            (z.addEventListener || "load" === event.type || "complete" === z.readyState) && (J(), n.ready())
        }
        n.ready.promise = function(b) {
            if (!I)
                if (I = n.Deferred(), "complete" === z.readyState) setTimeout(n.ready);
                else if (z.addEventListener) z.addEventListener("DOMContentLoaded", K, !1), a.addEventListener("load", K, !1);
            else {
                z.attachEvent("onreadystatechange", K), a.attachEvent("onload", K);
                var c = !1;
                try {
                    c = null == a.frameElement && z.documentElement
                } catch (d) {}
                c && c.doScroll && ! function e() {
                    if (!n.isReady) {
                        try {
                            c.doScroll("left")
                        } catch (a) {
                            return setTimeout(e, 50)
                        }
                        J(), n.ready()
                    }
                }()
            }
            return I.promise(b)
        };
        var L = "undefined",
            M;
        for (M in n(l)) break;
        l.ownLast = "0" !== M, l.inlineBlockNeedsLayout = !1, n(function() {
                var a, b, c = z.getElementsByTagName("body")[0];
                c && (a = z.createElement("div"), a.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px", b = z.createElement("div"), c.appendChild(a).appendChild(b), typeof b.style.zoom !== L && (b.style.cssText = "border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1", (l.inlineBlockNeedsLayout = 3 === b.offsetWidth) && (c.style.zoom = 1)), c.removeChild(a), a = b = null)
            }),
            function() {
                var a = z.createElement("div");
                if (null == l.deleteExpando) {
                    l.deleteExpando = !0;
                    try {
                        delete a.test
                    } catch (b) {
                        l.deleteExpando = !1
                    }
                }
                a = null
            }(), n.acceptData = function(a) {
                var b = n.noData[(a.nodeName + " ").toLowerCase()],
                    c = +a.nodeType || 1;
                return 1 !== c && 9 !== c ? !1 : !b || b !== !0 && a.getAttribute("classid") === b
            };
        var N = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
            O = /([A-Z])/g;
    
        function P(a, b, c) {
            if (void 0 === c && 1 === a.nodeType) {
                var d = "data-" + b.replace(O, "-$1").toLowerCase();
                if (c = a.getAttribute(d), "string" == typeof c) {
                    try {
                        c = "true" === c ? !0 : "false" === c ? !1 : "null" === c ? null : +c + "" === c ? +c : N.test(c) ? n.parseJSON(c) : c
                    } catch (e) {}
                    n.data(a, b, c)
                } else c = void 0
            }
            return c
        }
    
        function Q(a) {
            var b;
            for (b in a)
                if (("data" !== b || !n.isEmptyObject(a[b])) && "toJSON" !== b) return !1;
            return !0
        }
    
        function R(a, b, d, e) {
            if (n.acceptData(a)) {
                var f, g, h = n.expando,
                    i = a.nodeType,
                    j = i ? n.cache : a,
                    k = i ? a[h] : a[h] && h;
                if (k && j[k] && (e || j[k].data) || void 0 !== d || "string" != typeof b) return k || (k = i ? a[h] = c.pop() || n.guid++ : h), j[k] || (j[k] = i ? {} : {
                    toJSON: n.noop
                }), ("object" == typeof b || "function" == typeof b) && (e ? j[k] = n.extend(j[k], b) : j[k].data = n.extend(j[k].data, b)), g = j[k], e || (g.data || (g.data = {}), g = g.data), void 0 !== d && (g[n.camelCase(b)] = d), "string" == typeof b ? (f = g[b], null == f && (f = g[n.camelCase(b)])) : f = g, f
            }
        }
    
        function S(a, b, c) {
            if (n.acceptData(a)) {
                var d, e, f = a.nodeType,
                    g = f ? n.cache : a,
                    h = f ? a[n.expando] : n.expando;
                if (g[h]) {
                    if (b && (d = c ? g[h] : g[h].data)) {
                        n.isArray(b) ? b = b.concat(n.map(b, n.camelCase)) : b in d ? b = [b] : (b = n.camelCase(b), b = b in d ? [b] : b.split(" ")), e = b.length;
                        while (e--) delete d[b[e]];
                        if (c ? !Q(d) : !n.isEmptyObject(d)) return
                    }(c || (delete g[h].data, Q(g[h]))) && (f ? n.cleanData([a], !0) : l.deleteExpando || g != g.window ? delete g[h] : g[h] = null)
                }
            }
        }
        n.extend({
            cache: {},
            noData: {
                "applet ": !0,
                "embed ": !0,
                "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
            },
            hasData: function(a) {
                return a = a.nodeType ? n.cache[a[n.expando]] : a[n.expando], !!a && !Q(a)
            },
            data: function(a, b, c) {
                return R(a, b, c)
            },
            removeData: function(a, b) {
                return S(a, b)
            },
            _data: function(a, b, c) {
                return R(a, b, c, !0)
            },
            _removeData: function(a, b) {
                return S(a, b, !0)
            }
        }), n.fn.extend({
            data: function(a, b) {
                var c, d, e, f = this[0],
                    g = f && f.attributes;
                if (void 0 === a) {
                    if (this.length && (e = n.data(f), 1 === f.nodeType && !n._data(f, "parsedAttrs"))) {
                        c = g.length;
                        while (c--) d = g[c].name, 0 === d.indexOf("data-") && (d = n.camelCase(d.slice(5)), P(f, d, e[d]));
                        n._data(f, "parsedAttrs", !0)
                    }
                    return e
                }
                return "object" == typeof a ? this.each(function() {
                    n.data(this, a)
                }) : arguments.length > 1 ? this.each(function() {
                    n.data(this, a, b)
                }) : f ? P(f, a, n.data(f, a)) : void 0
            },
            removeData: function(a) {
                return this.each(function() {
                    n.removeData(this, a)
                })
            }
        }), n.extend({
            queue: function(a, b, c) {
                var d;
                return a ? (b = (b || "fx") + "queue", d = n._data(a, b), c && (!d || n.isArray(c) ? d = n._data(a, b, n.makeArray(c)) : d.push(c)), d || []) : void 0
            },
            dequeue: function(a, b) {
                b = b || "fx";
                var c = n.queue(a, b),
                    d = c.length,
                    e = c.shift(),
                    f = n._queueHooks(a, b),
                    g = function() {
                        n.dequeue(a, b)
                    };
                "inprogress" === e && (e = c.shift(), d--), e && ("fx" === b && c.unshift("inprogress"), delete f.stop, e.call(a, g, f)), !d && f && f.empty.fire()
            },
            _queueHooks: function(a, b) {
                var c = b + "queueHooks";
                return n._data(a, c) || n._data(a, c, {
                    empty: n.Callbacks("once memory").add(function() {
                        n._removeData(a, b + "queue"), n._removeData(a, c)
                    })
                })
            }
        }), n.fn.extend({
            queue: function(a, b) {
                var c = 2;
                return "string" != typeof a && (b = a, a = "fx", c--), arguments.length < c ? n.queue(this[0], a) : void 0 === b ? this : this.each(function() {
                    var c = n.queue(this, a, b);
                    n._queueHooks(this, a), "fx" === a && "inprogress" !== c[0] && n.dequeue(this, a)
                })
            },
            dequeue: function(a) {
                return this.each(function() {
                    n.dequeue(this, a)
                })
            },
            clearQueue: function(a) {
                return this.queue(a || "fx", [])
            },
            promise: function(a, b) {
                var c, d = 1,
                    e = n.Deferred(),
                    f = this,
                    g = this.length,
                    h = function() {
                        --d || e.resolveWith(f, [f])
                    };
                "string" != typeof a && (b = a, a = void 0), a = a || "fx";
                while (g--) c = n._data(f[g], a + "queueHooks"), c && c.empty && (d++, c.empty.add(h));
                return h(), e.promise(b)
            }
        });
        var T = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
            U = ["Top", "Right", "Bottom", "Left"],
            V = function(a, b) {
                return a = b || a, "none" === n.css(a, "display") || !n.contains(a.ownerDocument, a)
            },
            W = n.access = function(a, b, c, d, e, f, g) {
                var h = 0,
                    i = a.length,
                    j = null == c;
                if ("object" === n.type(c)) {
                    e = !0;
                    for (h in c) n.access(a, b, h, c[h], !0, f, g)
                } else if (void 0 !== d && (e = !0, n.isFunction(d) || (g = !0), j && (g ? (b.call(a, d), b = null) : (j = b, b = function(a, b, c) {
                        return j.call(n(a), c)
                    })), b))
                    for (; i > h; h++) b(a[h], c, g ? d : d.call(a[h], h, b(a[h], c)));
                return e ? a : j ? b.call(a) : i ? b(a[0], c) : f
            },
            X = /^(?:checkbox|radio)$/i;
        ! function() {
            var a = z.createDocumentFragment(),
                b = z.createElement("div"),
                c = z.createElement("input");
            if (b.setAttribute("className", "t"), b.innerHTML = "  <link/><table></table><a href='/a'>a</a>", l.leadingWhitespace = 3 === b.firstChild.nodeType, l.tbody = !b.getElementsByTagName("tbody").length, l.htmlSerialize = !!b.getElementsByTagName("link").length, l.html5Clone = "<:nav></:nav>" !== z.createElement("nav").cloneNode(!0).outerHTML, c.type = "checkbox", c.checked = !0, a.appendChild(c), l.appendChecked = c.checked, b.innerHTML = "<textarea>x</textarea>", l.noCloneChecked = !!b.cloneNode(!0).lastChild.defaultValue, a.appendChild(b), b.innerHTML = "<input type='radio' checked='checked' name='t'/>", l.checkClone = b.cloneNode(!0).cloneNode(!0).lastChild.checked, l.noCloneEvent = !0, b.attachEvent && (b.attachEvent("onclick", function() {
                    l.noCloneEvent = !1
                }), b.cloneNode(!0).click()), null == l.deleteExpando) {
                l.deleteExpando = !0;
                try {
                    delete b.test
                } catch (d) {
                    l.deleteExpando = !1
                }
            }
            a = b = c = null
        }(),
        function() {
            var b, c, d = z.createElement("div");
            for (b in {
                    submit: !0,
                    change: !0,
                    focusin: !0
                }) c = "on" + b, (l[b + "Bubbles"] = c in a) || (d.setAttribute(c, "t"), l[b + "Bubbles"] = d.attributes[c].expando === !1);
            d = null
        }();
        var Y = /^(?:input|select|textarea)$/i,
            Z = /^key/,
            $ = /^(?:mouse|contextmenu)|click/,
            _ = /^(?:focusinfocus|focusoutblur)$/,
            ab = /^([^.]*)(?:\.(.+)|)$/;
    
        function bb() {
            return !0
        }
    
        function cb() {
            return !1
        }
    
        function db() {
            try {
                return z.activeElement
            } catch (a) {}
        }
        n.event = {
            global: {},
            add: function(a, b, c, d, e) {
                var f, g, h, i, j, k, l, m, o, p, q, r = n._data(a);
                if (r) {
                    c.handler && (i = c, c = i.handler, e = i.selector), c.guid || (c.guid = n.guid++), (g = r.events) || (g = r.events = {}), (k = r.handle) || (k = r.handle = function(a) {
                        return typeof n === L || a && n.event.triggered === a.type ? void 0 : n.event.dispatch.apply(k.elem, arguments)
                    }, k.elem = a), b = (b || "").match(F) || [""], h = b.length;
                    while (h--) f = ab.exec(b[h]) || [], o = q = f[1], p = (f[2] || "").split(".").sort(), o && (j = n.event.special[o] || {}, o = (e ? j.delegateType : j.bindType) || o, j = n.event.special[o] || {}, l = n.extend({
                        type: o,
                        origType: q,
                        data: d,
                        handler: c,
                        guid: c.guid,
                        selector: e,
                        needsContext: e && n.expr.match.needsContext.test(e),
                        namespace: p.join(".")
                    }, i), (m = g[o]) || (m = g[o] = [], m.delegateCount = 0, j.setup && j.setup.call(a, d, p, k) !== !1 || (a.addEventListener ? a.addEventListener(o, k, !1) : a.attachEvent && a.attachEvent("on" + o, k))), j.add && (j.add.call(a, l), l.handler.guid || (l.handler.guid = c.guid)), e ? m.splice(m.delegateCount++, 0, l) : m.push(l), n.event.global[o] = !0);
                    a = null
                }
            },
            remove: function(a, b, c, d, e) {
                var f, g, h, i, j, k, l, m, o, p, q, r = n.hasData(a) && n._data(a);
                if (r && (k = r.events)) {
                    b = (b || "").match(F) || [""], j = b.length;
                    while (j--)
                        if (h = ab.exec(b[j]) || [], o = q = h[1], p = (h[2] || "").split(".").sort(), o) {
                            l = n.event.special[o] || {}, o = (d ? l.delegateType : l.bindType) || o, m = k[o] || [], h = h[2] && new RegExp("(^|\\.)" + p.join("\\.(?:.*\\.|)") + "(\\.|$)"), i = f = m.length;
                            while (f--) g = m[f], !e && q !== g.origType || c && c.guid !== g.guid || h && !h.test(g.namespace) || d && d !== g.selector && ("**" !== d || !g.selector) || (m.splice(f, 1), g.selector && m.delegateCount--, l.remove && l.remove.call(a, g));
                            i && !m.length && (l.teardown && l.teardown.call(a, p, r.handle) !== !1 || n.removeEvent(a, o, r.handle), delete k[o])
                        } else
                            for (o in k) n.event.remove(a, o + b[j], c, d, !0);
                    n.isEmptyObject(k) && (delete r.handle, n._removeData(a, "events"))
                }
            },
            trigger: function(b, c, d, e) {
                var f, g, h, i, k, l, m, o = [d || z],
                    p = j.call(b, "type") ? b.type : b,
                    q = j.call(b, "namespace") ? b.namespace.split(".") : [];
                if (h = l = d = d || z, 3 !== d.nodeType && 8 !== d.nodeType && !_.test(p + n.event.triggered) && (p.indexOf(".") >= 0 && (q = p.split("."), p = q.shift(), q.sort()), g = p.indexOf(":") < 0 && "on" + p, b = b[n.expando] ? b : new n.Event(p, "object" == typeof b && b), b.isTrigger = e ? 2 : 3, b.namespace = q.join("."), b.namespace_re = b.namespace ? new RegExp("(^|\\.)" + q.join("\\.(?:.*\\.|)") + "(\\.|$)") : null, b.result = void 0, b.target || (b.target = d), c = null == c ? [b] : n.makeArray(c, [b]), k = n.event.special[p] || {}, e || !k.trigger || k.trigger.apply(d, c) !== !1)) {
                    if (!e && !k.noBubble && !n.isWindow(d)) {
                        for (i = k.delegateType || p, _.test(i + p) || (h = h.parentNode); h; h = h.parentNode) o.push(h), l = h;
                        l === (d.ownerDocument || z) && o.push(l.defaultView || l.parentWindow || a)
                    }
                    m = 0;
                    while ((h = o[m++]) && !b.isPropagationStopped()) b.type = m > 1 ? i : k.bindType || p, f = (n._data(h, "events") || {})[b.type] && n._data(h, "handle"), f && f.apply(h, c), f = g && h[g], f && f.apply && n.acceptData(h) && (b.result = f.apply(h, c), b.result === !1 && b.preventDefault());
                    if (b.type = p, !e && !b.isDefaultPrevented() && (!k._default || k._default.apply(o.pop(), c) === !1) && n.acceptData(d) && g && d[p] && !n.isWindow(d)) {
                        l = d[g], l && (d[g] = null), n.event.triggered = p;
                        try {
                            d[p]()
                        } catch (r) {}
                        n.event.triggered = void 0, l && (d[g] = l)
                    }
                    return b.result
                }
            },
            dispatch: function(a) {
                a = n.event.fix(a);
                var b, c, e, f, g, h = [],
                    i = d.call(arguments),
                    j = (n._data(this, "events") || {})[a.type] || [],
                    k = n.event.special[a.type] || {};
                if (i[0] = a, a.delegateTarget = this, !k.preDispatch || k.preDispatch.call(this, a) !== !1) {
                    h = n.event.handlers.call(this, a, j), b = 0;
                    while ((f = h[b++]) && !a.isPropagationStopped()) {
                        a.currentTarget = f.elem, g = 0;
                        while ((e = f.handlers[g++]) && !a.isImmediatePropagationStopped())(!a.namespace_re || a.namespace_re.test(e.namespace)) && (a.handleObj = e, a.data = e.data, c = ((n.event.special[e.origType] || {}).handle || e.handler).apply(f.elem, i), void 0 !== c && (a.result = c) === !1 && (a.preventDefault(), a.stopPropagation()))
                    }
                    return k.postDispatch && k.postDispatch.call(this, a), a.result
                }
            },
            handlers: function(a, b) {
                var c, d, e, f, g = [],
                    h = b.delegateCount,
                    i = a.target;
                if (h && i.nodeType && (!a.button || "click" !== a.type))
                    for (; i != this; i = i.parentNode || this)
                        if (1 === i.nodeType && (i.disabled !== !0 || "click" !== a.type)) {
                            for (e = [], f = 0; h > f; f++) d = b[f], c = d.selector + " ", void 0 === e[c] && (e[c] = d.needsContext ? n(c, this).index(i) >= 0 : n.find(c, this, null, [i]).length), e[c] && e.push(d);
                            e.length && g.push({
                                elem: i,
                                handlers: e
                            })
                        }
                return h < b.length && g.push({
                    elem: this,
                    handlers: b.slice(h)
                }), g
            },
            fix: function(a) {
                if (a[n.expando]) return a;
                var b, c, d, e = a.type,
                    f = a,
                    g = this.fixHooks[e];
                g || (this.fixHooks[e] = g = $.test(e) ? this.mouseHooks : Z.test(e) ? this.keyHooks : {}), d = g.props ? this.props.concat(g.props) : this.props, a = new n.Event(f), b = d.length;
                while (b--) c = d[b], a[c] = f[c];
                return a.target || (a.target = f.srcElement || z), 3 === a.target.nodeType && (a.target = a.target.parentNode), a.metaKey = !!a.metaKey, g.filter ? g.filter(a, f) : a
            },
            props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
            fixHooks: {},
            keyHooks: {
                props: "char charCode key keyCode".split(" "),
                filter: function(a, b) {
                    return null == a.which && (a.which = null != b.charCode ? b.charCode : b.keyCode), a
                }
            },
            mouseHooks: {
                props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
                filter: function(a, b) {
                    var c, d, e, f = b.button,
                        g = b.fromElement;
                    return null == a.pageX && null != b.clientX && (d = a.target.ownerDocument || z, e = d.documentElement, c = d.body, a.pageX = b.clientX + (e && e.scrollLeft || c && c.scrollLeft || 0) - (e && e.clientLeft || c && c.clientLeft || 0), a.pageY = b.clientY + (e && e.scrollTop || c && c.scrollTop || 0) - (e && e.clientTop || c && c.clientTop || 0)), !a.relatedTarget && g && (a.relatedTarget = g === a.target ? b.toElement : g), a.which || void 0 === f || (a.which = 1 & f ? 1 : 2 & f ? 3 : 4 & f ? 2 : 0), a
                }
            },
            special: {
                load: {
                    noBubble: !0
                },
                focus: {
                    trigger: function() {
                        if (this !== db() && this.focus) try {
                            return this.focus(), !1
                        } catch (a) {}
                    },
                    delegateType: "focusin"
                },
                blur: {
                    trigger: function() {
                        return this === db() && this.blur ? (this.blur(), !1) : void 0
                    },
                    delegateType: "focusout"
                },
                click: {
                    trigger: function() {
                        return n.nodeName(this, "input") && "checkbox" === this.type && this.click ? (this.click(), !1) : void 0
                    },
                    _default: function(a) {
                        return n.nodeName(a.target, "a")
                    }
                },
                beforeunload: {
                    postDispatch: function(a) {
                        void 0 !== a.result && (a.originalEvent.returnValue = a.result)
                    }
                }
            },
            simulate: function(a, b, c, d) {
                var e = n.extend(new n.Event, c, {
                    type: a,
                    isSimulated: !0,
                    originalEvent: {}
                });
                d ? n.event.trigger(e, null, b) : n.event.dispatch.call(b, e), e.isDefaultPrevented() && c.preventDefault()
            }
        }, n.removeEvent = z.removeEventListener ? function(a, b, c) {
            a.removeEventListener && a.removeEventListener(b, c, !1)
        } : function(a, b, c) {
            var d = "on" + b;
            a.detachEvent && (typeof a[d] === L && (a[d] = null), a.detachEvent(d, c))
        }, n.Event = function(a, b) {
            return this instanceof n.Event ? (a && a.type ? (this.originalEvent = a, this.type = a.type, this.isDefaultPrevented = a.defaultPrevented || void 0 === a.defaultPrevented && (a.returnValue === !1 || a.getPreventDefault && a.getPreventDefault()) ? bb : cb) : this.type = a, b && n.extend(this, b), this.timeStamp = a && a.timeStamp || n.now(), void(this[n.expando] = !0)) : new n.Event(a, b)
        }, n.Event.prototype = {
            isDefaultPrevented: cb,
            isPropagationStopped: cb,
            isImmediatePropagationStopped: cb,
            preventDefault: function() {
                var a = this.originalEvent;
                this.isDefaultPrevented = bb, a && (a.preventDefault ? a.preventDefault() : a.returnValue = !1)
            },
            stopPropagation: function() {
                var a = this.originalEvent;
                this.isPropagationStopped = bb, a && (a.stopPropagation && a.stopPropagation(), a.cancelBubble = !0)
            },
            stopImmediatePropagation: function() {
                this.isImmediatePropagationStopped = bb, this.stopPropagation()
            }
        }, n.each({
            mouseenter: "mouseover",
            mouseleave: "mouseout"
        }, function(a, b) {
            n.event.special[a] = {
                delegateType: b,
                bindType: b,
                handle: function(a) {
                    var c, d = this,
                        e = a.relatedTarget,
                        f = a.handleObj;
                    return (!e || e !== d && !n.contains(d, e)) && (a.type = f.origType, c = f.handler.apply(this, arguments), a.type = b), c
                }
            }
        }), l.submitBubbles || (n.event.special.submit = {
            setup: function() {
                return n.nodeName(this, "form") ? !1 : void n.event.add(this, "click._submit keypress._submit", function(a) {
                    var b = a.target,
                        c = n.nodeName(b, "input") || n.nodeName(b, "button") ? b.form : void 0;
                    c && !n._data(c, "submitBubbles") && (n.event.add(c, "submit._submit", function(a) {
                        a._submit_bubble = !0
                    }), n._data(c, "submitBubbles", !0))
                })
            },
            postDispatch: function(a) {
                a._submit_bubble && (delete a._submit_bubble, this.parentNode && !a.isTrigger && n.event.simulate("submit", this.parentNode, a, !0))
            },
            teardown: function() {
                return n.nodeName(this, "form") ? !1 : void n.event.remove(this, "._submit")
            }
        }), l.changeBubbles || (n.event.special.change = {
            setup: function() {
                return Y.test(this.nodeName) ? (("checkbox" === this.type || "radio" === this.type) && (n.event.add(this, "propertychange._change", function(a) {
                    "checked" === a.originalEvent.propertyName && (this._just_changed = !0)
                }), n.event.add(this, "click._change", function(a) {
                    this._just_changed && !a.isTrigger && (this._just_changed = !1), n.event.simulate("change", this, a, !0)
                })), !1) : void n.event.add(this, "beforeactivate._change", function(a) {
                    var b = a.target;
                    Y.test(b.nodeName) && !n._data(b, "changeBubbles") && (n.event.add(b, "change._change", function(a) {
                        !this.parentNode || a.isSimulated || a.isTrigger || n.event.simulate("change", this.parentNode, a, !0)
                    }), n._data(b, "changeBubbles", !0))
                })
            },
            handle: function(a) {
                var b = a.target;
                return this !== b || a.isSimulated || a.isTrigger || "radio" !== b.type && "checkbox" !== b.type ? a.handleObj.handler.apply(this, arguments) : void 0
            },
            teardown: function() {
                return n.event.remove(this, "._change"), !Y.test(this.nodeName)
            }
        }), l.focusinBubbles || n.each({
            focus: "focusin",
            blur: "focusout"
        }, function(a, b) {
            var c = function(a) {
                n.event.simulate(b, a.target, n.event.fix(a), !0)
            };
            n.event.special[b] = {
                setup: function() {
                    var d = this.ownerDocument || this,
                        e = n._data(d, b);
                    e || d.addEventListener(a, c, !0), n._data(d, b, (e || 0) + 1)
                },
                teardown: function() {
                    var d = this.ownerDocument || this,
                        e = n._data(d, b) - 1;
                    e ? n._data(d, b, e) : (d.removeEventListener(a, c, !0), n._removeData(d, b))
                }
            }
        }), n.fn.extend({
            on: function(a, b, c, d, e) {
                var f, g;
                if ("object" == typeof a) {
                    "string" != typeof b && (c = c || b, b = void 0);
                    for (f in a) this.on(f, b, c, a[f], e);
                    return this
                }
                if (null == c && null == d ? (d = b, c = b = void 0) : null == d && ("string" == typeof b ? (d = c, c = void 0) : (d = c, c = b, b = void 0)), d === !1) d = cb;
                else if (!d) return this;
                return 1 === e && (g = d, d = function(a) {
                    return n().off(a), g.apply(this, arguments)
                }, d.guid = g.guid || (g.guid = n.guid++)), this.each(function() {
                    n.event.add(this, a, d, c, b)
                })
            },
            one: function(a, b, c, d) {
                return this.on(a, b, c, d, 1)
            },
            off: function(a, b, c) {
                var d, e;
                if (a && a.preventDefault && a.handleObj) return d = a.handleObj, n(a.delegateTarget).off(d.namespace ? d.origType + "." + d.namespace : d.origType, d.selector, d.handler), this;
                if ("object" == typeof a) {
                    for (e in a) this.off(e, b, a[e]);
                    return this
                }
                return (b === !1 || "function" == typeof b) && (c = b, b = void 0), c === !1 && (c = cb), this.each(function() {
                    n.event.remove(this, a, c, b)
                })
            },
            trigger: function(a, b) {
                return this.each(function() {
                    n.event.trigger(a, b, this)
                })
            },
            triggerHandler: function(a, b) {
                var c = this[0];
                return c ? n.event.trigger(a, b, c, !0) : void 0
            }
        });
    
        function eb(a) {
            var b = fb.split("|"),
                c = a.createDocumentFragment();
            if (c.createElement)
                while (b.length) c.createElement(b.pop());
            return c
        }
        var fb = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
            gb = / jQuery\d+="(?:null|\d+)"/g,
            hb = new RegExp("<(?:" + fb + ")[\\s/>]", "i"),
            ib = /^\s+/,
            jb = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
            kb = /<([\w:]+)/,
            lb = /<tbody/i,
            mb = /<|&#?\w+;/,
            nb = /<(?:script|style|link)/i,
            ob = /checked\s*(?:[^=]|=\s*.checked.)/i,
            pb = /^$|\/(?:java|ecma)script/i,
            qb = /^true\/(.*)/,
            rb = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
            sb = {
                option: [1, "<select multiple='multiple'>", "</select>"],
                legend: [1, "<fieldset>", "</fieldset>"],
                area: [1, "<map>", "</map>"],
                param: [1, "<object>", "</object>"],
                thead: [1, "<table>", "</table>"],
                tr: [2, "<table><tbody>", "</tbody></table>"],
                col: [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"],
                td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
                _default: l.htmlSerialize ? [0, "", ""] : [1, "X<div>", "</div>"]
            },
            tb = eb(z),
            ub = tb.appendChild(z.createElement("div"));
        sb.optgroup = sb.option, sb.tbody = sb.tfoot = sb.colgroup = sb.caption = sb.thead, sb.th = sb.td;
    
        function vb(a, b) {
            var c, d, e = 0,
                f = typeof a.getElementsByTagName !== L ? a.getElementsByTagName(b || "*") : typeof a.querySelectorAll !== L ? a.querySelectorAll(b || "*") : void 0;
            if (!f)
                for (f = [], c = a.childNodes || a; null != (d = c[e]); e++) !b || n.nodeName(d, b) ? f.push(d) : n.merge(f, vb(d, b));
            return void 0 === b || b && n.nodeName(a, b) ? n.merge([a], f) : f
        }
    
        function wb(a) {
            X.test(a.type) && (a.defaultChecked = a.checked)
        }
    
        function xb(a, b) {
            return n.nodeName(a, "table") && n.nodeName(11 !== b.nodeType ? b : b.firstChild, "tr") ? a.getElementsByTagName("tbody")[0] || a.appendChild(a.ownerDocument.createElement("tbody")) : a
        }
    
        function yb(a) {
            return a.type = (null !== n.find.attr(a, "type")) + "/" + a.type, a
        }
    
        function zb(a) {
            var b = qb.exec(a.type);
            return b ? a.type = b[1] : a.removeAttribute("type"), a
        }
    
        function Ab(a, b) {
            for (var c, d = 0; null != (c = a[d]); d++) n._data(c, "globalEval", !b || n._data(b[d], "globalEval"))
        }
    
        function Bb(a, b) {
            if (1 === b.nodeType && n.hasData(a)) {
                var c, d, e, f = n._data(a),
                    g = n._data(b, f),
                    h = f.events;
                if (h) {
                    delete g.handle, g.events = {};
                    for (c in h)
                        for (d = 0, e = h[c].length; e > d; d++) n.event.add(b, c, h[c][d])
                }
                g.data && (g.data = n.extend({}, g.data))
            }
        }
    
        function Cb(a, b) {
            var c, d, e;
            if (1 === b.nodeType) {
                if (c = b.nodeName.toLowerCase(), !l.noCloneEvent && b[n.expando]) {
                    e = n._data(b);
                    for (d in e.events) n.removeEvent(b, d, e.handle);
                    b.removeAttribute(n.expando)
                }
                "script" === c && b.text !== a.text ? (yb(b).text = a.text, zb(b)) : "object" === c ? (b.parentNode && (b.outerHTML = a.outerHTML), l.html5Clone && a.innerHTML && !n.trim(b.innerHTML) && (b.innerHTML = a.innerHTML)) : "input" === c && X.test(a.type) ? (b.defaultChecked = b.checked = a.checked, b.value !== a.value && (b.value = a.value)) : "option" === c ? b.defaultSelected = b.selected = a.defaultSelected : ("input" === c || "textarea" === c) && (b.defaultValue = a.defaultValue)
            }
        }
        n.extend({
            clone: function(a, b, c) {
                var d, e, f, g, h, i = n.contains(a.ownerDocument, a);
                if (l.html5Clone || n.isXMLDoc(a) || !hb.test("<" + a.nodeName + ">") ? f = a.cloneNode(!0) : (ub.innerHTML = a.outerHTML, ub.removeChild(f = ub.firstChild)), !(l.noCloneEvent && l.noCloneChecked || 1 !== a.nodeType && 11 !== a.nodeType || n.isXMLDoc(a)))
                    for (d = vb(f), h = vb(a), g = 0; null != (e = h[g]); ++g) d[g] && Cb(e, d[g]);
                if (b)
                    if (c)
                        for (h = h || vb(a), d = d || vb(f), g = 0; null != (e = h[g]); g++) Bb(e, d[g]);
                    else Bb(a, f);
                return d = vb(f, "script"), d.length > 0 && Ab(d, !i && vb(a, "script")), d = h = e = null, f
            },
            buildFragment: function(a, b, c, d) {
                for (var e, f, g, h, i, j, k, m = a.length, o = eb(b), p = [], q = 0; m > q; q++)
                    if (f = a[q], f || 0 === f)
                        if ("object" === n.type(f)) n.merge(p, f.nodeType ? [f] : f);
                        else if (mb.test(f)) {
                    h = h || o.appendChild(b.createElement("div")), i = (kb.exec(f) || ["", ""])[1].toLowerCase(), k = sb[i] || sb._default, h.innerHTML = k[1] + f.replace(jb, "<$1></$2>") + k[2], e = k[0];
                    while (e--) h = h.lastChild;
                    if (!l.leadingWhitespace && ib.test(f) && p.push(b.createTextNode(ib.exec(f)[0])), !l.tbody) {
                        f = "table" !== i || lb.test(f) ? "<table>" !== k[1] || lb.test(f) ? 0 : h : h.firstChild, e = f && f.childNodes.length;
                        while (e--) n.nodeName(j = f.childNodes[e], "tbody") && !j.childNodes.length && f.removeChild(j)
                    }
                    n.merge(p, h.childNodes), h.textContent = "";
                    while (h.firstChild) h.removeChild(h.firstChild);
                    h = o.lastChild
                } else p.push(b.createTextNode(f));
                h && o.removeChild(h), l.appendChecked || n.grep(vb(p, "input"), wb), q = 0;
                while (f = p[q++])
                    if ((!d || -1 === n.inArray(f, d)) && (g = n.contains(f.ownerDocument, f), h = vb(o.appendChild(f), "script"), g && Ab(h), c)) {
                        e = 0;
                        while (f = h[e++]) pb.test(f.type || "") && c.push(f)
                    }
                return h = null, o
            },
            cleanData: function(a, b) {
                for (var d, e, f, g, h = 0, i = n.expando, j = n.cache, k = l.deleteExpando, m = n.event.special; null != (d = a[h]); h++)
                    if ((b || n.acceptData(d)) && (f = d[i], g = f && j[f])) {
                        if (g.events)
                            for (e in g.events) m[e] ? n.event.remove(d, e) : n.removeEvent(d, e, g.handle);
                        j[f] && (delete j[f], k ? delete d[i] : typeof d.removeAttribute !== L ? d.removeAttribute(i) : d[i] = null, c.push(f))
                    }
            }
        }), n.fn.extend({
            text: function(a) {
                return W(this, function(a) {
                    return void 0 === a ? n.text(this) : this.empty().append((this[0] && this[0].ownerDocument || z).createTextNode(a))
                }, null, a, arguments.length)
            },
            append: function() {
                return this.domManip(arguments, function(a) {
                    if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) {
                        var b = xb(this, a);
                        b.appendChild(a)
                    }
                })
            },
            prepend: function() {
                return this.domManip(arguments, function(a) {
                    if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) {
                        var b = xb(this, a);
                        b.insertBefore(a, b.firstChild)
                    }
                })
            },
            before: function() {
                return this.domManip(arguments, function(a) {
                    this.parentNode && this.parentNode.insertBefore(a, this)
                })
            },
            after: function() {
                return this.domManip(arguments, function(a) {
                    this.parentNode && this.parentNode.insertBefore(a, this.nextSibling)
                })
            },
            remove: function(a, b) {
                for (var c, d = a ? n.filter(a, this) : this, e = 0; null != (c = d[e]); e++) b || 1 !== c.nodeType || n.cleanData(vb(c)), c.parentNode && (b && n.contains(c.ownerDocument, c) && Ab(vb(c, "script")), c.parentNode.removeChild(c));
                return this
            },
            empty: function() {
                for (var a, b = 0; null != (a = this[b]); b++) {
                    1 === a.nodeType && n.cleanData(vb(a, !1));
                    while (a.firstChild) a.removeChild(a.firstChild);
                    a.options && n.nodeName(a, "select") && (a.options.length = 0)
                }
                return this
            },
            clone: function(a, b) {
                return a = null == a ? !1 : a, b = null == b ? a : b, this.map(function() {
                    return n.clone(this, a, b)
                })
            },
            html: function(a) {
                return W(this, function(a) {
                    var b = this[0] || {},
                        c = 0,
                        d = this.length;
                    if (void 0 === a) return 1 === b.nodeType ? b.innerHTML.replace(gb, "") : void 0;
                    if (!("string" != typeof a || nb.test(a) || !l.htmlSerialize && hb.test(a) || !l.leadingWhitespace && ib.test(a) || sb[(kb.exec(a) || ["", ""])[1].toLowerCase()])) {
                        a = a.replace(jb, "<$1></$2>");
                        try {
                            for (; d > c; c++) b = this[c] || {}, 1 === b.nodeType && (n.cleanData(vb(b, !1)), b.innerHTML = a);
                            b = 0
                        } catch (e) {}
                    }
                    b && this.empty().append(a)
                }, null, a, arguments.length)
            },
            replaceWith: function() {
                var a = arguments[0];
                return this.domManip(arguments, function(b) {
                    a = this.parentNode, n.cleanData(vb(this)), a && a.replaceChild(b, this)
                }), a && (a.length || a.nodeType) ? this : this.remove()
            },
            detach: function(a) {
                return this.remove(a, !0)
            },
            domManip: function(a, b) {
                a = e.apply([], a);
                var c, d, f, g, h, i, j = 0,
                    k = this.length,
                    m = this,
                    o = k - 1,
                    p = a[0],
                    q = n.isFunction(p);
                if (q || k > 1 && "string" == typeof p && !l.checkClone && ob.test(p)) return this.each(function(c) {
                    var d = m.eq(c);
                    q && (a[0] = p.call(this, c, d.html())), d.domManip(a, b)
                });
                if (k && (i = n.buildFragment(a, this[0].ownerDocument, !1, this), c = i.firstChild, 1 === i.childNodes.length && (i = c), c)) {
                    for (g = n.map(vb(i, "script"), yb), f = g.length; k > j; j++) d = i, j !== o && (d = n.clone(d, !0, !0), f && n.merge(g, vb(d, "script"))), b.call(this[j], d, j);
                    if (f)
                        for (h = g[g.length - 1].ownerDocument, n.map(g, zb), j = 0; f > j; j++) d = g[j], pb.test(d.type || "") && !n._data(d, "globalEval") && n.contains(h, d) && (d.src ? n._evalUrl && n._evalUrl(d.src) : n.globalEval((d.text || d.textContent || d.innerHTML || "").replace(rb, "")));
                    i = c = null
                }
                return this
            }
        }), n.each({
            appendTo: "append",
            prependTo: "prepend",
            insertBefore: "before",
            insertAfter: "after",
            replaceAll: "replaceWith"
        }, function(a, b) {
            n.fn[a] = function(a) {
                for (var c, d = 0, e = [], g = n(a), h = g.length - 1; h >= d; d++) c = d === h ? this : this.clone(!0), n(g[d])[b](c), f.apply(e, c.get());
                return this.pushStack(e)
            }
        });
        var Db, Eb = {};
    
        function Fb(b, c) {
            var d = n(c.createElement(b)).appendTo(c.body),
                e = a.getDefaultComputedStyle ? a.getDefaultComputedStyle(d[0]).display : n.css(d[0], "display");
            return d.detach(), e
        }
    
        function Gb(a) {
            var b = z,
                c = Eb[a];
            return c || (c = Fb(a, b), "none" !== c && c || (Db = (Db || n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement), b = (Db[0].contentWindow || Db[0].contentDocument).document, b.write(), b.close(), c = Fb(a, b), Db.detach()), Eb[a] = c), c
        }! function() {
            var a, b, c = z.createElement("div"),
                d = "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";
            c.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>", a = c.getElementsByTagName("a")[0], a.style.cssText = "float:left;opacity:.5", l.opacity = /^0.5/.test(a.style.opacity), l.cssFloat = !!a.style.cssFloat, c.style.backgroundClip = "content-box", c.cloneNode(!0).style.backgroundClip = "", l.clearCloneStyle = "content-box" === c.style.backgroundClip, a = c = null, l.shrinkWrapBlocks = function() {
                var a, c, e, f;
                if (null == b) {
                    if (a = z.getElementsByTagName("body")[0], !a) return;
                    f = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px", c = z.createElement("div"), e = z.createElement("div"), a.appendChild(c).appendChild(e), b = !1, typeof e.style.zoom !== L && (e.style.cssText = d + ";width:1px;padding:1px;zoom:1", e.innerHTML = "<div></div>", e.firstChild.style.width = "5px", b = 3 !== e.offsetWidth), a.removeChild(c), a = c = e = null
                }
                return b
            }
        }();
        var Hb = /^margin/,
            Ib = new RegExp("^(" + T + ")(?!px)[a-z%]+$", "i"),
            Jb, Kb, Lb = /^(top|right|bottom|left)$/;
        a.getComputedStyle ? (Jb = function(a) {
            return a.ownerDocument.defaultView.getComputedStyle(a, null)
        }, Kb = function(a, b, c) {
            var d, e, f, g, h = a.style;
            return c = c || Jb(a), g = c ? c.getPropertyValue(b) || c[b] : void 0, c && ("" !== g || n.contains(a.ownerDocument, a) || (g = n.style(a, b)), Ib.test(g) && Hb.test(b) && (d = h.width, e = h.minWidth, f = h.maxWidth, h.minWidth = h.maxWidth = h.width = g, g = c.width, h.width = d, h.minWidth = e, h.maxWidth = f)), void 0 === g ? g : g + ""
        }) : z.documentElement.currentStyle && (Jb = function(a) {
            return a.currentStyle
        }, Kb = function(a, b, c) {
            var d, e, f, g, h = a.style;
            return c = c || Jb(a), g = c ? c[b] : void 0, null == g && h && h[b] && (g = h[b]), Ib.test(g) && !Lb.test(b) && (d = h.left, e = a.runtimeStyle, f = e && e.left, f && (e.left = a.currentStyle.left), h.left = "fontSize" === b ? "1em" : g, g = h.pixelLeft + "px", h.left = d, f && (e.left = f)), void 0 === g ? g : g + "" || "auto"
        });
    
        function Mb(a, b) {
            return {
                get: function() {
                    var c = a();
                    if (null != c) return c ? void delete this.get : (this.get = b).apply(this, arguments)
                }
            }
        }! function() {
            var b, c, d, e, f, g, h = z.createElement("div"),
                i = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px",
                j = "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";
            h.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>", b = h.getElementsByTagName("a")[0], b.style.cssText = "float:left;opacity:.5", l.opacity = /^0.5/.test(b.style.opacity), l.cssFloat = !!b.style.cssFloat, h.style.backgroundClip = "content-box", h.cloneNode(!0).style.backgroundClip = "", l.clearCloneStyle = "content-box" === h.style.backgroundClip, b = h = null, n.extend(l, {
                reliableHiddenOffsets: function() {
                    if (null != c) return c;
                    var a, b, d, e = z.createElement("div"),
                        f = z.getElementsByTagName("body")[0];
                    if (f) return e.setAttribute("className", "t"), e.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>", a = z.createElement("div"), a.style.cssText = i, f.appendChild(a).appendChild(e), e.innerHTML = "<table><tr><td></td><td>t</td></tr></table>", b = e.getElementsByTagName("td"), b[0].style.cssText = "padding:0;margin:0;border:0;display:none", d = 0 === b[0].offsetHeight, b[0].style.display = "", b[1].style.display = "none", c = d && 0 === b[0].offsetHeight, f.removeChild(a), e = f = null, c
                },
                boxSizing: function() {
                    return null == d && k(), d
                },
                boxSizingReliable: function() {
                    return null == e && k(), e
                },
                pixelPosition: function() {
                    return null == f && k(), f
                },
                reliableMarginRight: function() {
                    var b, c, d, e;
                    if (null == g && a.getComputedStyle) {
                        if (b = z.getElementsByTagName("body")[0], !b) return;
                        c = z.createElement("div"), d = z.createElement("div"), c.style.cssText = i, b.appendChild(c).appendChild(d), e = d.appendChild(z.createElement("div")), e.style.cssText = d.style.cssText = j, e.style.marginRight = e.style.width = "0", d.style.width = "1px", g = !parseFloat((a.getComputedStyle(e, null) || {}).marginRight), b.removeChild(c)
                    }
                    return g
                }
            });
    
            function k() {
                var b, c, h = z.getElementsByTagName("body")[0];
                h && (b = z.createElement("div"), c = z.createElement("div"), b.style.cssText = i, h.appendChild(b).appendChild(c), c.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;display:block;padding:1px;border:1px;width:4px;margin-top:1%;top:1%", n.swap(h, null != h.style.zoom ? {
                    zoom: 1
                } : {}, function() {
                    d = 4 === c.offsetWidth
                }), e = !0, f = !1, g = !0, a.getComputedStyle && (f = "1%" !== (a.getComputedStyle(c, null) || {}).top, e = "4px" === (a.getComputedStyle(c, null) || {
                    width: "4px"
                }).width), h.removeChild(b), c = h = null)
            }
        }(), n.swap = function(a, b, c, d) {
            var e, f, g = {};
            for (f in b) g[f] = a.style[f], a.style[f] = b[f];
            e = c.apply(a, d || []);
            for (f in b) a.style[f] = g[f];
            return e
        };
        var Nb = /alpha\([^)]*\)/i,
            Ob = /opacity\s*=\s*([^)]*)/,
            Pb = /^(none|table(?!-c[ea]).+)/,
            Qb = new RegExp("^(" + T + ")(.*)$", "i"),
            Rb = new RegExp("^([+-])=(" + T + ")", "i"),
            Sb = {
                position: "absolute",
                visibility: "hidden",
                display: "block"
            },
            Tb = {
                letterSpacing: 0,
                fontWeight: 400
            },
            Ub = ["Webkit", "O", "Moz", "ms"];
    
        function Vb(a, b) {
            if (b in a) return b;
            var c = b.charAt(0).toUpperCase() + b.slice(1),
                d = b,
                e = Ub.length;
            while (e--)
                if (b = Ub[e] + c, b in a) return b;
            return d
        }
    
        function Wb(a, b) {
            for (var c, d, e, f = [], g = 0, h = a.length; h > g; g++) d = a[g], d.style && (f[g] = n._data(d, "olddisplay"), c = d.style.display, b ? (f[g] || "none" !== c || (d.style.display = ""), "" === d.style.display && V(d) && (f[g] = n._data(d, "olddisplay", Gb(d.nodeName)))) : f[g] || (e = V(d), (c && "none" !== c || !e) && n._data(d, "olddisplay", e ? c : n.css(d, "display"))));
            for (g = 0; h > g; g++) d = a[g], d.style && (b && "none" !== d.style.display && "" !== d.style.display || (d.style.display = b ? f[g] || "" : "none"));
            return a
        }
    
        function Xb(a, b, c) {
            var d = Qb.exec(b);
            return d ? Math.max(0, d[1] - (c || 0)) + (d[2] || "px") : b
        }
    
        function Yb(a, b, c, d, e) {
            for (var f = c === (d ? "border" : "content") ? 4 : "width" === b ? 1 : 0, g = 0; 4 > f; f += 2) "margin" === c && (g += n.css(a, c + U[f], !0, e)), d ? ("content" === c && (g -= n.css(a, "padding" + U[f], !0, e)), "margin" !== c && (g -= n.css(a, "border" + U[f] + "Width", !0, e))) : (g += n.css(a, "padding" + U[f], !0, e), "padding" !== c && (g += n.css(a, "border" + U[f] + "Width", !0, e)));
            return g
        }
    
        function Zb(a, b, c) {
            var d = !0,
                e = "width" === b ? a.offsetWidth : a.offsetHeight,
                f = Jb(a),
                g = l.boxSizing() && "border-box" === n.css(a, "boxSizing", !1, f);
            if (0 >= e || null == e) {
                if (e = Kb(a, b, f), (0 > e || null == e) && (e = a.style[b]), Ib.test(e)) return e;
                d = g && (l.boxSizingReliable() || e === a.style[b]), e = parseFloat(e) || 0
            }
            return e + Yb(a, b, c || (g ? "border" : "content"), d, f) + "px"
        }
        n.extend({
            cssHooks: {
                opacity: {
                    get: function(a, b) {
                        if (b) {
                            var c = Kb(a, "opacity");
                            return "" === c ? "1" : c
                        }
                    }
                }
            },
            cssNumber: {
                columnCount: !0,
                fillOpacity: !0,
                fontWeight: !0,
                lineHeight: !0,
                opacity: !0,
                order: !0,
                orphans: !0,
                widows: !0,
                zIndex: !0,
                zoom: !0
            },
            cssProps: {
                "float": l.cssFloat ? "cssFloat" : "styleFloat"
            },
            style: function(a, b, c, d) {
                if (a && 3 !== a.nodeType && 8 !== a.nodeType && a.style) {
                    var e, f, g, h = n.camelCase(b),
                        i = a.style;
                    if (b = n.cssProps[h] || (n.cssProps[h] = Vb(i, h)), g = n.cssHooks[b] || n.cssHooks[h], void 0 === c) return g && "get" in g && void 0 !== (e = g.get(a, !1, d)) ? e : i[b];
                    if (f = typeof c, "string" === f && (e = Rb.exec(c)) && (c = (e[1] + 1) * e[2] + parseFloat(n.css(a, b)), f = "number"), null != c && c === c && ("number" !== f || n.cssNumber[h] || (c += "px"), l.clearCloneStyle || "" !== c || 0 !== b.indexOf("background") || (i[b] = "inherit"), !(g && "set" in g && void 0 === (c = g.set(a, c, d))))) try {
                        i[b] = "", i[b] = c
                    } catch (j) {}
                }
            },
            css: function(a, b, c, d) {
                var e, f, g, h = n.camelCase(b);
                return b = n.cssProps[h] || (n.cssProps[h] = Vb(a.style, h)), g = n.cssHooks[b] || n.cssHooks[h], g && "get" in g && (f = g.get(a, !0, c)), void 0 === f && (f = Kb(a, b, d)), "normal" === f && b in Tb && (f = Tb[b]), "" === c || c ? (e = parseFloat(f), c === !0 || n.isNumeric(e) ? e || 0 : f) : f
            }
        }), n.each(["height", "width"], function(a, b) {
            n.cssHooks[b] = {
                get: function(a, c, d) {
                    return c ? 0 === a.offsetWidth && Pb.test(n.css(a, "display")) ? n.swap(a, Sb, function() {
                        return Zb(a, b, d)
                    }) : Zb(a, b, d) : void 0
                },
                set: function(a, c, d) {
                    var e = d && Jb(a);
                    return Xb(a, c, d ? Yb(a, b, d, l.boxSizing() && "border-box" === n.css(a, "boxSizing", !1, e), e) : 0)
                }
            }
        }), l.opacity || (n.cssHooks.opacity = {
            get: function(a, b) {
                return Ob.test((b && a.currentStyle ? a.currentStyle.filter : a.style.filter) || "") ? .01 * parseFloat(RegExp.$1) + "" : b ? "1" : ""
            },
            set: function(a, b) {
                var c = a.style,
                    d = a.currentStyle,
                    e = n.isNumeric(b) ? "alpha(opacity=" + 100 * b + ")" : "",
                    f = d && d.filter || c.filter || "";
                c.zoom = 1, (b >= 1 || "" === b) && "" === n.trim(f.replace(Nb, "")) && c.removeAttribute && (c.removeAttribute("filter"), "" === b || d && !d.filter) || (c.filter = Nb.test(f) ? f.replace(Nb, e) : f + " " + e)
            }
        }), n.cssHooks.marginRight = Mb(l.reliableMarginRight, function(a, b) {
            return b ? n.swap(a, {
                display: "inline-block"
            }, Kb, [a, "marginRight"]) : void 0
        }), n.each({
            margin: "",
            padding: "",
            border: "Width"
        }, function(a, b) {
            n.cssHooks[a + b] = {
                expand: function(c) {
                    for (var d = 0, e = {}, f = "string" == typeof c ? c.split(" ") : [c]; 4 > d; d++) e[a + U[d] + b] = f[d] || f[d - 2] || f[0];
                    return e
                }
            }, Hb.test(a) || (n.cssHooks[a + b].set = Xb)
        }), n.fn.extend({
            css: function(a, b) {
                return W(this, function(a, b, c) {
                    var d, e, f = {},
                        g = 0;
                    if (n.isArray(b)) {
                        for (d = Jb(a), e = b.length; e > g; g++) f[b[g]] = n.css(a, b[g], !1, d);
                        return f
                    }
                    return void 0 !== c ? n.style(a, b, c) : n.css(a, b)
                }, a, b, arguments.length > 1)
            },
            show: function() {
                return Wb(this, !0)
            },
            hide: function() {
                return Wb(this)
            },
            toggle: function(a) {
                return "boolean" == typeof a ? a ? this.show() : this.hide() : this.each(function() {
                    V(this) ? n(this).show() : n(this).hide()
                })
            }
        });
    
        function $b(a, b, c, d, e) {
            return new $b.prototype.init(a, b, c, d, e)
        }
        n.Tween = $b, $b.prototype = {
            constructor: $b,
            init: function(a, b, c, d, e, f) {
                this.elem = a, this.prop = c, this.easing = e || "swing", this.options = b, this.start = this.now = this.cur(), this.end = d, this.unit = f || (n.cssNumber[c] ? "" : "px")
            },
            cur: function() {
                var a = $b.propHooks[this.prop];
                return a && a.get ? a.get(this) : $b.propHooks._default.get(this)
            },
            run: function(a) {
                var b, c = $b.propHooks[this.prop];
                return this.pos = b = this.options.duration ? n.easing[this.easing](a, this.options.duration * a, 0, 1, this.options.duration) : a, this.now = (this.end - this.start) * b + this.start, this.options.step && this.options.step.call(this.elem, this.now, this), c && c.set ? c.set(this) : $b.propHooks._default.set(this), this
            }
        }, $b.prototype.init.prototype = $b.prototype, $b.propHooks = {
            _default: {
                get: function(a) {
                    var b;
                    return null == a.elem[a.prop] || a.elem.style && null != a.elem.style[a.prop] ? (b = n.css(a.elem, a.prop, ""), b && "auto" !== b ? b : 0) : a.elem[a.prop]
                },
                set: function(a) {
                    n.fx.step[a.prop] ? n.fx.step[a.prop](a) : a.elem.style && (null != a.elem.style[n.cssProps[a.prop]] || n.cssHooks[a.prop]) ? n.style(a.elem, a.prop, a.now + a.unit) : a.elem[a.prop] = a.now
                }
            }
        }, $b.propHooks.scrollTop = $b.propHooks.scrollLeft = {
            set: function(a) {
                a.elem.nodeType && a.elem.parentNode && (a.elem[a.prop] = a.now)
            }
        }, n.easing = {
            linear: function(a) {
                return a
            },
            swing: function(a) {
                return .5 - Math.cos(a * Math.PI) / 2
            }
        }, n.fx = $b.prototype.init, n.fx.step = {};
        var _b, ac, bc = /^(?:toggle|show|hide)$/,
            cc = new RegExp("^(?:([+-])=|)(" + T + ")([a-z%]*)$", "i"),
            dc = /queueHooks$/,
            ec = [jc],
            fc = {
                "*": [function(a, b) {
                    var c = this.createTween(a, b),
                        d = c.cur(),
                        e = cc.exec(b),
                        f = e && e[3] || (n.cssNumber[a] ? "" : "px"),
                        g = (n.cssNumber[a] || "px" !== f && +d) && cc.exec(n.css(c.elem, a)),
                        h = 1,
                        i = 20;
                    if (g && g[3] !== f) {
                        f = f || g[3], e = e || [], g = +d || 1;
                        do h = h || ".5", g /= h, n.style(c.elem, a, g + f); while (h !== (h = c.cur() / d) && 1 !== h && --i)
                    }
                    return e && (g = c.start = +g || +d || 0, c.unit = f, c.end = e[1] ? g + (e[1] + 1) * e[2] : +e[2]), c
                }]
            };
    
        function gc() {
            return setTimeout(function() {
                _b = void 0
            }), _b = n.now()
        }
    
        function hc(a, b) {
            var c, d = {
                    height: a
                },
                e = 0;
            for (b = b ? 1 : 0; 4 > e; e += 2 - b) c = U[e], d["margin" + c] = d["padding" + c] = a;
            return b && (d.opacity = d.width = a), d
        }
    
        function ic(a, b, c) {
            for (var d, e = (fc[b] || []).concat(fc["*"]), f = 0, g = e.length; g > f; f++)
                if (d = e[f].call(c, b, a)) return d
        }
    
        function jc(a, b, c) {
            var d, e, f, g, h, i, j, k, m = this,
                o = {},
                p = a.style,
                q = a.nodeType && V(a),
                r = n._data(a, "fxshow");
            c.queue || (h = n._queueHooks(a, "fx"), null == h.unqueued && (h.unqueued = 0, i = h.empty.fire, h.empty.fire = function() {
                h.unqueued || i()
            }), h.unqueued++, m.always(function() {
                m.always(function() {
                    h.unqueued--, n.queue(a, "fx").length || h.empty.fire()
                })
            })), 1 === a.nodeType && ("height" in b || "width" in b) && (c.overflow = [p.overflow, p.overflowX, p.overflowY], j = n.css(a, "display"), k = Gb(a.nodeName), "none" === j && (j = k), "inline" === j && "none" === n.css(a, "float") && (l.inlineBlockNeedsLayout && "inline" !== k ? p.zoom = 1 : p.display = "inline-block")), c.overflow && (p.overflow = "hidden", l.shrinkWrapBlocks() || m.always(function() {
                p.overflow = c.overflow[0], p.overflowX = c.overflow[1], p.overflowY = c.overflow[2]
            }));
            for (d in b)
                if (e = b[d], bc.exec(e)) {
                    if (delete b[d], f = f || "toggle" === e, e === (q ? "hide" : "show")) {
                        if ("show" !== e || !r || void 0 === r[d]) continue;
                        q = !0
                    }
                    o[d] = r && r[d] || n.style(a, d)
                }
            if (!n.isEmptyObject(o)) {
                r ? "hidden" in r && (q = r.hidden) : r = n._data(a, "fxshow", {}), f && (r.hidden = !q), q ? n(a).show() : m.done(function() {
                    n(a).hide()
                }), m.done(function() {
                    var b;
                    n._removeData(a, "fxshow");
                    for (b in o) n.style(a, b, o[b])
                });
                for (d in o) g = ic(q ? r[d] : 0, d, m), d in r || (r[d] = g.start, q && (g.end = g.start, g.start = "width" === d || "height" === d ? 1 : 0))
            }
        }
    
        function kc(a, b) {
            var c, d, e, f, g;
            for (c in a)
                if (d = n.camelCase(c), e = b[d], f = a[c], n.isArray(f) && (e = f[1], f = a[c] = f[0]), c !== d && (a[d] = f, delete a[c]), g = n.cssHooks[d], g && "expand" in g) {
                    f = g.expand(f), delete a[d];
                    for (c in f) c in a || (a[c] = f[c], b[c] = e)
                } else b[d] = e
        }
    
        function lc(a, b, c) {
            var d, e, f = 0,
                g = ec.length,
                h = n.Deferred().always(function() {
                    delete i.elem
                }),
                i = function() {
                    if (e) return !1;
                    for (var b = _b || gc(), c = Math.max(0, j.startTime + j.duration - b), d = c / j.duration || 0, f = 1 - d, g = 0, i = j.tweens.length; i > g; g++) j.tweens[g].run(f);
                    return h.notifyWith(a, [j, f, c]), 1 > f && i ? c : (h.resolveWith(a, [j]), !1)
                },
                j = h.promise({
                    elem: a,
                    props: n.extend({}, b),
                    opts: n.extend(!0, {
                        specialEasing: {}
                    }, c),
                    originalProperties: b,
                    originalOptions: c,
                    startTime: _b || gc(),
                    duration: c.duration,
                    tweens: [],
                    createTween: function(b, c) {
                        var d = n.Tween(a, j.opts, b, c, j.opts.specialEasing[b] || j.opts.easing);
                        return j.tweens.push(d), d
                    },
                    stop: function(b) {
                        var c = 0,
                            d = b ? j.tweens.length : 0;
                        if (e) return this;
                        for (e = !0; d > c; c++) j.tweens[c].run(1);
                        return b ? h.resolveWith(a, [j, b]) : h.rejectWith(a, [j, b]), this
                    }
                }),
                k = j.props;
            for (kc(k, j.opts.specialEasing); g > f; f++)
                if (d = ec[f].call(j, a, k, j.opts)) return d;
            return n.map(k, ic, j), n.isFunction(j.opts.start) && j.opts.start.call(a, j), n.fx.timer(n.extend(i, {
                elem: a,
                anim: j,
                queue: j.opts.queue
            })), j.progress(j.opts.progress).done(j.opts.done, j.opts.complete).fail(j.opts.fail).always(j.opts.always)
        }
        n.Animation = n.extend(lc, {
                tweener: function(a, b) {
                    n.isFunction(a) ? (b = a, a = ["*"]) : a = a.split(" ");
                    for (var c, d = 0, e = a.length; e > d; d++) c = a[d], fc[c] = fc[c] || [], fc[c].unshift(b)
                },
                prefilter: function(a, b) {
                    b ? ec.unshift(a) : ec.push(a)
                }
            }), n.speed = function(a, b, c) {
                var d = a && "object" == typeof a ? n.extend({}, a) : {
                    complete: c || !c && b || n.isFunction(a) && a,
                    duration: a,
                    easing: c && b || b && !n.isFunction(b) && b
                };
                return d.duration = n.fx.off ? 0 : "number" == typeof d.duration ? d.duration : d.duration in n.fx.speeds ? n.fx.speeds[d.duration] : n.fx.speeds._default, (null == d.queue || d.queue === !0) && (d.queue = "fx"), d.old = d.complete, d.complete = function() {
                    n.isFunction(d.old) && d.old.call(this), d.queue && n.dequeue(this, d.queue)
                }, d
            }, n.fn.extend({
                fadeTo: function(a, b, c, d) {
                    return this.filter(V).css("opacity", 0).show().end().animate({
                        opacity: b
                    }, a, c, d)
                },
                animate: function(a, b, c, d) {
                    var e = n.isEmptyObject(a),
                        f = n.speed(b, c, d),
                        g = function() {
                            var b = lc(this, n.extend({}, a), f);
                            (e || n._data(this, "finish")) && b.stop(!0)
                        };
                    return g.finish = g, e || f.queue === !1 ? this.each(g) : this.queue(f.queue, g)
                },
                stop: function(a, b, c) {
                    var d = function(a) {
                        var b = a.stop;
                        delete a.stop, b(c)
                    };
                    return "string" != typeof a && (c = b, b = a, a = void 0), b && a !== !1 && this.queue(a || "fx", []), this.each(function() {
                        var b = !0,
                            e = null != a && a + "queueHooks",
                            f = n.timers,
                            g = n._data(this);
                        if (e) g[e] && g[e].stop && d(g[e]);
                        else
                            for (e in g) g[e] && g[e].stop && dc.test(e) && d(g[e]);
                        for (e = f.length; e--;) f[e].elem !== this || null != a && f[e].queue !== a || (f[e].anim.stop(c), b = !1, f.splice(e, 1));
                        (b || !c) && n.dequeue(this, a)
                    })
                },
                finish: function(a) {
                    return a !== !1 && (a = a || "fx"), this.each(function() {
                        var b, c = n._data(this),
                            d = c[a + "queue"],
                            e = c[a + "queueHooks"],
                            f = n.timers,
                            g = d ? d.length : 0;
                        for (c.finish = !0, n.queue(this, a, []), e && e.stop && e.stop.call(this, !0), b = f.length; b--;) f[b].elem === this && f[b].queue === a && (f[b].anim.stop(!0), f.splice(b, 1));
                        for (b = 0; g > b; b++) d[b] && d[b].finish && d[b].finish.call(this);
                        delete c.finish
                    })
                }
            }), n.each(["toggle", "show", "hide"], function(a, b) {
                var c = n.fn[b];
                n.fn[b] = function(a, d, e) {
                    return null == a || "boolean" == typeof a ? c.apply(this, arguments) : this.animate(hc(b, !0), a, d, e)
                }
            }), n.each({
                slideDown: hc("show"),
                slideUp: hc("hide"),
                slideToggle: hc("toggle"),
                fadeIn: {
                    opacity: "show"
                },
                fadeOut: {
                    opacity: "hide"
                },
                fadeToggle: {
                    opacity: "toggle"
                }
            }, function(a, b) {
                n.fn[a] = function(a, c, d) {
                    return this.animate(b, a, c, d)
                }
            }), n.timers = [], n.fx.tick = function() {
                var a, b = n.timers,
                    c = 0;
                for (_b = n.now(); c < b.length; c++) a = b[c], a() || b[c] !== a || b.splice(c--, 1);
                b.length || n.fx.stop(), _b = void 0
            }, n.fx.timer = function(a) {
                n.timers.push(a), a() ? n.fx.start() : n.timers.pop()
            }, n.fx.interval = 13, n.fx.start = function() {
                ac || (ac = setInterval(n.fx.tick, n.fx.interval))
            }, n.fx.stop = function() {
                clearInterval(ac), ac = null
            }, n.fx.speeds = {
                slow: 600,
                fast: 200,
                _default: 400
            }, n.fn.delay = function(a, b) {
                return a = n.fx ? n.fx.speeds[a] || a : a, b = b || "fx", this.queue(b, function(b, c) {
                    var d = setTimeout(b, a);
                    c.stop = function() {
                        clearTimeout(d)
                    }
                })
            },
            function() {
                var a, b, c, d, e = z.createElement("div");
                e.setAttribute("className", "t"), e.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>", a = e.getElementsByTagName("a")[0], c = z.createElement("select"), d = c.appendChild(z.createElement("option")), b = e.getElementsByTagName("input")[0], a.style.cssText = "top:1px", l.getSetAttribute = "t" !== e.className, l.style = /top/.test(a.getAttribute("style")), l.hrefNormalized = "/a" === a.getAttribute("href"), l.checkOn = !!b.value, l.optSelected = d.selected, l.enctype = !!z.createElement("form").enctype, c.disabled = !0, l.optDisabled = !d.disabled, b = z.createElement("input"), b.setAttribute("value", ""), l.input = "" === b.getAttribute("value"), b.value = "t", b.setAttribute("type", "radio"), l.radioValue = "t" === b.value, a = b = c = d = e = null
            }();
        var mc = /\r/g;
        n.fn.extend({
            val: function(a) {
                var b, c, d, e = this[0]; {
                    if (arguments.length) return d = n.isFunction(a), this.each(function(c) {
                        var e;
                        1 === this.nodeType && (e = d ? a.call(this, c, n(this).val()) : a, null == e ? e = "" : "number" == typeof e ? e += "" : n.isArray(e) && (e = n.map(e, function(a) {
                            return null == a ? "" : a + ""
                        })), b = n.valHooks[this.type] || n.valHooks[this.nodeName.toLowerCase()], b && "set" in b && void 0 !== b.set(this, e, "value") || (this.value = e))
                    });
                    if (e) return b = n.valHooks[e.type] || n.valHooks[e.nodeName.toLowerCase()], b && "get" in b && void 0 !== (c = b.get(e, "value")) ? c : (c = e.value, "string" == typeof c ? c.replace(mc, "") : null == c ? "" : c)
                }
            }
        }), n.extend({
            valHooks: {
                option: {
                    get: function(a) {
                        var b = n.find.attr(a, "value");
                        return null != b ? b : n.text(a)
                    }
                },
                select: {
                    get: function(a) {
                        for (var b, c, d = a.options, e = a.selectedIndex, f = "select-one" === a.type || 0 > e, g = f ? null : [], h = f ? e + 1 : d.length, i = 0 > e ? h : f ? e : 0; h > i; i++)
                            if (c = d[i], !(!c.selected && i !== e || (l.optDisabled ? c.disabled : null !== c.getAttribute("disabled")) || c.parentNode.disabled && n.nodeName(c.parentNode, "optgroup"))) {
                                if (b = n(c).val(), f) return b;
                                g.push(b)
                            }
                        return g
                    },
                    set: function(a, b) {
                        var c, d, e = a.options,
                            f = n.makeArray(b),
                            g = e.length;
                        while (g--)
                            if (d = e[g], n.inArray(n.valHooks.option.get(d), f) >= 0) try {
                                d.selected = c = !0
                            } catch (h) {
                                d.scrollHeight
                            } else d.selected = !1;
                        return c || (a.selectedIndex = -1), e
                    }
                }
            }
        }), n.each(["radio", "checkbox"], function() {
            n.valHooks[this] = {
                set: function(a, b) {
                    return n.isArray(b) ? a.checked = n.inArray(n(a).val(), b) >= 0 : void 0
                }
            }, l.checkOn || (n.valHooks[this].get = function(a) {
                return null === a.getAttribute("value") ? "on" : a.value
            })
        });
        var nc, oc, pc = n.expr.attrHandle,
            qc = /^(?:checked|selected)$/i,
            rc = l.getSetAttribute,
            sc = l.input;
        n.fn.extend({
            attr: function(a, b) {
                return W(this, n.attr, a, b, arguments.length > 1)
            },
            removeAttr: function(a) {
                return this.each(function() {
                    n.removeAttr(this, a)
                })
            }
        }), n.extend({
            attr: function(a, b, c) {
                var d, e, f = a.nodeType;
                if (a && 3 !== f && 8 !== f && 2 !== f) return typeof a.getAttribute === L ? n.prop(a, b, c) : (1 === f && n.isXMLDoc(a) || (b = b.toLowerCase(), d = n.attrHooks[b] || (n.expr.match.bool.test(b) ? oc : nc)), void 0 === c ? d && "get" in d && null !== (e = d.get(a, b)) ? e : (e = n.find.attr(a, b), null == e ? void 0 : e) : null !== c ? d && "set" in d && void 0 !== (e = d.set(a, c, b)) ? e : (a.setAttribute(b, c + ""), c) : void n.removeAttr(a, b))
            },
            removeAttr: function(a, b) {
                var c, d, e = 0,
                    f = b && b.match(F);
                if (f && 1 === a.nodeType)
                    while (c = f[e++]) d = n.propFix[c] || c, n.expr.match.bool.test(c) ? sc && rc || !qc.test(c) ? a[d] = !1 : a[n.camelCase("default-" + c)] = a[d] = !1 : n.attr(a, c, ""), a.removeAttribute(rc ? c : d)
            },
            attrHooks: {
                type: {
                    set: function(a, b) {
                        if (!l.radioValue && "radio" === b && n.nodeName(a, "input")) {
                            var c = a.value;
                            return a.setAttribute("type", b), c && (a.value = c), b
                        }
                    }
                }
            }
        }), oc = {
            set: function(a, b, c) {
                return b === !1 ? n.removeAttr(a, c) : sc && rc || !qc.test(c) ? a.setAttribute(!rc && n.propFix[c] || c, c) : a[n.camelCase("default-" + c)] = a[c] = !0, c
            }
        }, n.each(n.expr.match.bool.source.match(/\w+/g), function(a, b) {
            var c = pc[b] || n.find.attr;
            pc[b] = sc && rc || !qc.test(b) ? function(a, b, d) {
                var e, f;
                return d || (f = pc[b], pc[b] = e, e = null != c(a, b, d) ? b.toLowerCase() : null, pc[b] = f), e
            } : function(a, b, c) {
                return c ? void 0 : a[n.camelCase("default-" + b)] ? b.toLowerCase() : null
            }
        }), sc && rc || (n.attrHooks.value = {
            set: function(a, b, c) {
                return n.nodeName(a, "input") ? void(a.defaultValue = b) : nc && nc.set(a, b, c)
            }
        }), rc || (nc = {
            set: function(a, b, c) {
                var d = a.getAttributeNode(c);
                return d || a.setAttributeNode(d = a.ownerDocument.createAttribute(c)), d.value = b += "", "value" === c || b === a.getAttribute(c) ? b : void 0
            }
        }, pc.id = pc.name = pc.coords = function(a, b, c) {
            var d;
            return c ? void 0 : (d = a.getAttributeNode(b)) && "" !== d.value ? d.value : null
        }, n.valHooks.button = {
            get: function(a, b) {
                var c = a.getAttributeNode(b);
                return c && c.specified ? c.value : void 0
            },
            set: nc.set
        }, n.attrHooks.contenteditable = {
            set: function(a, b, c) {
                nc.set(a, "" === b ? !1 : b, c)
            }
        }, n.each(["width", "height"], function(a, b) {
            n.attrHooks[b] = {
                set: function(a, c) {
                    return "" === c ? (a.setAttribute(b, "auto"), c) : void 0
                }
            }
        })), l.style || (n.attrHooks.style = {
            get: function(a) {
                return a.style.cssText || void 0
            },
            set: function(a, b) {
                return a.style.cssText = b + ""
            }
        });
        var tc = /^(?:input|select|textarea|button|object)$/i,
            uc = /^(?:a|area)$/i;
        n.fn.extend({
            prop: function(a, b) {
                return W(this, n.prop, a, b, arguments.length > 1)
            },
            removeProp: function(a) {
                return a = n.propFix[a] || a, this.each(function() {
                    try {
                        this[a] = void 0, delete this[a]
                    } catch (b) {}
                })
            }
        }), n.extend({
            propFix: {
                "for": "htmlFor",
                "class": "className"
            },
            prop: function(a, b, c) {
                var d, e, f, g = a.nodeType;
                if (a && 3 !== g && 8 !== g && 2 !== g) return f = 1 !== g || !n.isXMLDoc(a), f && (b = n.propFix[b] || b, e = n.propHooks[b]), void 0 !== c ? e && "set" in e && void 0 !== (d = e.set(a, c, b)) ? d : a[b] = c : e && "get" in e && null !== (d = e.get(a, b)) ? d : a[b]
            },
            propHooks: {
                tabIndex: {
                    get: function(a) {
                        var b = n.find.attr(a, "tabindex");
                        return b ? parseInt(b, 10) : tc.test(a.nodeName) || uc.test(a.nodeName) && a.href ? 0 : -1
                    }
                }
            }
        }), l.hrefNormalized || n.each(["href", "src"], function(a, b) {
            n.propHooks[b] = {
                get: function(a) {
                    return a.getAttribute(b, 4)
                }
            }
        }), l.optSelected || (n.propHooks.selected = {
            get: function(a) {
                var b = a.parentNode;
                return b && (b.selectedIndex, b.parentNode && b.parentNode.selectedIndex), null
            }
        }), n.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function() {
            n.propFix[this.toLowerCase()] = this
        }), l.enctype || (n.propFix.enctype = "encoding");
        var vc = /[\t\r\n\f]/g;
        n.fn.extend({
            addClass: function(a) {
                var b, c, d, e, f, g, h = 0,
                    i = this.length,
                    j = "string" == typeof a && a;
                if (n.isFunction(a)) return this.each(function(b) {
                    n(this).addClass(a.call(this, b, this.className))
                });
                if (j)
                    for (b = (a || "").match(F) || []; i > h; h++)
                        if (c = this[h], d = 1 === c.nodeType && (c.className ? (" " + c.className + " ").replace(vc, " ") : " ")) {
                            f = 0;
                            while (e = b[f++]) d.indexOf(" " + e + " ") < 0 && (d += e + " ");
                            g = n.trim(d), c.className !== g && (c.className = g)
                        }
                return this
            },
            removeClass: function(a) {
                var b, c, d, e, f, g, h = 0,
                    i = this.length,
                    j = 0 === arguments.length || "string" == typeof a && a;
                if (n.isFunction(a)) return this.each(function(b) {
                    n(this).removeClass(a.call(this, b, this.className))
                });
                if (j)
                    for (b = (a || "").match(F) || []; i > h; h++)
                        if (c = this[h], d = 1 === c.nodeType && (c.className ? (" " + c.className + " ").replace(vc, " ") : "")) {
                            f = 0;
                            while (e = b[f++])
                                while (d.indexOf(" " + e + " ") >= 0) d = d.replace(" " + e + " ", " ");
                            g = a ? n.trim(d) : "", c.className !== g && (c.className = g)
                        }
                return this
            },
            toggleClass: function(a, b) {
                var c = typeof a;
                return "boolean" == typeof b && "string" === c ? b ? this.addClass(a) : this.removeClass(a) : this.each(n.isFunction(a) ? function(c) {
                    n(this).toggleClass(a.call(this, c, this.className, b), b)
                } : function() {
                    if ("string" === c) {
                        var b, d = 0,
                            e = n(this),
                            f = a.match(F) || [];
                        while (b = f[d++]) e.hasClass(b) ? e.removeClass(b) : e.addClass(b)
                    } else(c === L || "boolean" === c) && (this.className && n._data(this, "__className__", this.className), this.className = this.className || a === !1 ? "" : n._data(this, "__className__") || "")
                })
            },
            hasClass: function(a) {
                for (var b = " " + a + " ", c = 0, d = this.length; d > c; c++)
                    if (1 === this[c].nodeType && (" " + this[c].className + " ").replace(vc, " ").indexOf(b) >= 0) return !0;
                return !1
            }
        }), n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "), function(a, b) {
            n.fn[b] = function(a, c) {
                return arguments.length > 0 ? this.on(b, null, a, c) : this.trigger(b)
            }
        }), n.fn.extend({
            hover: function(a, b) {
                return this.mouseenter(a).mouseleave(b || a)
            },
            bind: function(a, b, c) {
                return this.on(a, null, b, c)
            },
            unbind: function(a, b) {
                return this.off(a, null, b)
            },
            delegate: function(a, b, c, d) {
                return this.on(b, a, c, d)
            },
            undelegate: function(a, b, c) {
                return 1 === arguments.length ? this.off(a, "**") : this.off(b, a || "**", c)
            }
        });
        var wc = n.now(),
            xc = /\?/,
            yc = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
        n.parseJSON = function(b) {
            if (a.JSON && a.JSON.parse) return a.JSON.parse(b + "");
            var c, d = null,
                e = n.trim(b + "");
            return e && !n.trim(e.replace(yc, function(a, b, e, f) {
                return c && b && (d = 0), 0 === d ? a : (c = e || b, d += !f - !e, "")
            })) ? Function("return " + e)() : n.error("Invalid JSON: " + b)
        }, n.parseXML = function(b) {
            var c, d;
            if (!b || "string" != typeof b) return null;
            try {
                a.DOMParser ? (d = new DOMParser, c = d.parseFromString(b, "text/xml")) : (c = new ActiveXObject("Microsoft.XMLDOM"), c.async = "false", c.loadXML(b))
            } catch (e) {
                c = void 0
            }
            return c && c.documentElement && !c.getElementsByTagName("parsererror").length || n.error("Invalid XML: " + b), c
        };
        var zc, Ac, Bc = /#.*$/,
            Cc = /([?&])_=[^&]*/,
            Dc = /^(.*?):[ \t]*([^\r\n]*)\r?$/gm,
            Ec = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
            Fc = /^(?:GET|HEAD)$/,
            Gc = /^\/\//,
            Hc = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
            Ic = {},
            Jc = {},
            Kc = "*/".concat("*");
        try {
            Ac = location.href
        } catch (Lc) {
            Ac = z.createElement("a"), Ac.href = "", Ac = Ac.href
        }
        zc = Hc.exec(Ac.toLowerCase()) || [];
    
        function Mc(a) {
            return function(b, c) {
                "string" != typeof b && (c = b, b = "*");
                var d, e = 0,
                    f = b.toLowerCase().match(F) || [];
                if (n.isFunction(c))
                    while (d = f[e++]) "+" === d.charAt(0) ? (d = d.slice(1) || "*", (a[d] = a[d] || []).unshift(c)) : (a[d] = a[d] || []).push(c)
            }
        }
    
        function Nc(a, b, c, d) {
            var e = {},
                f = a === Jc;
    
            function g(h) {
                var i;
                return e[h] = !0, n.each(a[h] || [], function(a, h) {
                    var j = h(b, c, d);
                    return "string" != typeof j || f || e[j] ? f ? !(i = j) : void 0 : (b.dataTypes.unshift(j), g(j), !1)
                }), i
            }
            return g(b.dataTypes[0]) || !e["*"] && g("*")
        }
    
        function Oc(a, b) {
            var c, d, e = n.ajaxSettings.flatOptions || {};
            for (d in b) void 0 !== b[d] && ((e[d] ? a : c || (c = {}))[d] = b[d]);
            return c && n.extend(!0, a, c), a
        }
    
        function Pc(a, b, c) {
            var d, e, f, g, h = a.contents,
                i = a.dataTypes;
            while ("*" === i[0]) i.shift(), void 0 === e && (e = a.mimeType || b.getResponseHeader("Content-Type"));
            if (e)
                for (g in h)
                    if (h[g] && h[g].test(e)) {
                        i.unshift(g);
                        break
                    }
            if (i[0] in c) f = i[0];
            else {
                for (g in c) {
                    if (!i[0] || a.converters[g + " " + i[0]]) {
                        f = g;
                        break
                    }
                    d || (d = g)
                }
                f = f || d
            }
            return f ? (f !== i[0] && i.unshift(f), c[f]) : void 0
        }
    
        function Qc(a, b, c, d) {
            var e, f, g, h, i, j = {},
                k = a.dataTypes.slice();
            if (k[1])
                for (g in a.converters) j[g.toLowerCase()] = a.converters[g];
            f = k.shift();
            while (f)
                if (a.responseFields[f] && (c[a.responseFields[f]] = b), !i && d && a.dataFilter && (b = a.dataFilter(b, a.dataType)), i = f, f = k.shift())
                    if ("*" === f) f = i;
                    else if ("*" !== i && i !== f) {
                if (g = j[i + " " + f] || j["* " + f], !g)
                    for (e in j)
                        if (h = e.split(" "), h[1] === f && (g = j[i + " " + h[0]] || j["* " + h[0]])) {
                            g === !0 ? g = j[e] : j[e] !== !0 && (f = h[0], k.unshift(h[1]));
                            break
                        }
                if (g !== !0)
                    if (g && a["throws"]) b = g(b);
                    else try {
                        b = g(b)
                    } catch (l) {
                        return {
                            state: "parsererror",
                            error: g ? l : "No conversion from " + i + " to " + f
                        }
                    }
            }
            return {
                state: "success",
                data: b
            }
        }
        n.extend({
            active: 0,
            lastModified: {},
            etag: {},
            ajaxSettings: {
                url: Ac,
                type: "GET",
                isLocal: Ec.test(zc[1]),
                global: !0,
                processData: !0,
                async: !0,
                contentType: "application/x-www-form-urlencoded; charset=UTF-8",
                accepts: {
                    "*": Kc,
                    text: "text/plain",
                    html: "text/html",
                    xml: "application/xml, text/xml",
                    json: "application/json, text/javascript"
                },
                contents: {
                    xml: /xml/,
                    html: /html/,
                    json: /json/
                },
                responseFields: {
                    xml: "responseXML",
                    text: "responseText",
                    json: "responseJSON"
                },
                converters: {
                    "* text": String,
                    "text html": !0,
                    "text json": n.parseJSON,
                    "text xml": n.parseXML
                },
                flatOptions: {
                    url: !0,
                    context: !0
                }
            },
            ajaxSetup: function(a, b) {
                return b ? Oc(Oc(a, n.ajaxSettings), b) : Oc(n.ajaxSettings, a)
            },
            ajaxPrefilter: Mc(Ic),
            ajaxTransport: Mc(Jc),
            ajax: function(a, b) {
                "object" == typeof a && (b = a, a = void 0), b = b || {};
                var c, d, e, f, g, h, i, j, k = n.ajaxSetup({}, b),
                    l = k.context || k,
                    m = k.context && (l.nodeType || l.jquery) ? n(l) : n.event,
                    o = n.Deferred(),
                    p = n.Callbacks("once memory"),
                    q = k.statusCode || {},
                    r = {},
                    s = {},
                    t = 0,
                    u = "canceled",
                    v = {
                        readyState: 0,
                        getResponseHeader: function(a) {
                            var b;
                            if (2 === t) {
                                if (!j) {
                                    j = {};
                                    while (b = Dc.exec(f)) j[b[1].toLowerCase()] = b[2]
                                }
                                b = j[a.toLowerCase()]
                            }
                            return null == b ? null : b
                        },
                        getAllResponseHeaders: function() {
                            return 2 === t ? f : null
                        },
                        setRequestHeader: function(a, b) {
                            var c = a.toLowerCase();
                            return t || (a = s[c] = s[c] || a, r[a] = b), this
                        },
                        overrideMimeType: function(a) {
                            return t || (k.mimeType = a), this
                        },
                        statusCode: function(a) {
                            var b;
                            if (a)
                                if (2 > t)
                                    for (b in a) q[b] = [q[b], a[b]];
                                else v.always(a[v.status]);
                            return this
                        },
                        abort: function(a) {
                            var b = a || u;
                            return i && i.abort(b), x(0, b), this
                        }
                    };
                if (o.promise(v).complete = p.add, v.success = v.done, v.error = v.fail, k.url = ((a || k.url || Ac) + "").replace(Bc, "").replace(Gc, zc[1] + "//"), k.type = b.method || b.type || k.method || k.type, k.dataTypes = n.trim(k.dataType || "*").toLowerCase().match(F) || [""], null == k.crossDomain && (c = Hc.exec(k.url.toLowerCase()), k.crossDomain = !(!c || c[1] === zc[1] && c[2] === zc[2] && (c[3] || ("http:" === c[1] ? "80" : "443")) === (zc[3] || ("http:" === zc[1] ? "80" : "443")))), k.data && k.processData && "string" != typeof k.data && (k.data = n.param(k.data, k.traditional)), Nc(Ic, k, b, v), 2 === t) return v;
                h = k.global, h && 0 === n.active++ && n.event.trigger("ajaxStart"), k.type = k.type.toUpperCase(), k.hasContent = !Fc.test(k.type), e = k.url, k.hasContent || (k.data && (e = k.url += (xc.test(e) ? "&" : "?") + k.data, delete k.data), k.cache === !1 && (k.url = Cc.test(e) ? e.replace(Cc, "$1_=" + wc++) : e + (xc.test(e) ? "&" : "?") + "_=" + wc++)), k.ifModified && (n.lastModified[e] && v.setRequestHeader("If-Modified-Since", n.lastModified[e]), n.etag[e] && v.setRequestHeader("If-None-Match", n.etag[e])), (k.data && k.hasContent && k.contentType !== !1 || b.contentType) && v.setRequestHeader("Content-Type", k.contentType), v.setRequestHeader("Accept", k.dataTypes[0] && k.accepts[k.dataTypes[0]] ? k.accepts[k.dataTypes[0]] + ("*" !== k.dataTypes[0] ? ", " + Kc + "; q=0.01" : "") : k.accepts["*"]);
                for (d in k.headers) v.setRequestHeader(d, k.headers[d]);
                if (k.beforeSend && (k.beforeSend.call(l, v, k) === !1 || 2 === t)) return v.abort();
                u = "abort";
                for (d in {
                        success: 1,
                        error: 1,
                        complete: 1
                    }) v[d](k[d]);
                if (i = Nc(Jc, k, b, v)) {
                    v.readyState = 1, h && m.trigger("ajaxSend", [v, k]), k.async && k.timeout > 0 && (g = setTimeout(function() {
                        v.abort("timeout")
                    }, k.timeout));
                    try {
                        t = 1, i.send(r, x)
                    } catch (w) {
                        if (!(2 > t)) throw w;
                        x(-1, w)
                    }
                } else x(-1, "No Transport");
    
                function x(a, b, c, d) {
                    var j, r, s, u, w, x = b;
                    2 !== t && (t = 2, g && clearTimeout(g), i = void 0, f = d || "", v.readyState = a > 0 ? 4 : 0, j = a >= 200 && 300 > a || 304 === a, c && (u = Pc(k, v, c)), u = Qc(k, u, v, j), j ? (k.ifModified && (w = v.getResponseHeader("Last-Modified"), w && (n.lastModified[e] = w), w = v.getResponseHeader("etag"), w && (n.etag[e] = w)), 204 === a || "HEAD" === k.type ? x = "nocontent" : 304 === a ? x = "notmodified" : (x = u.state, r = u.data, s = u.error, j = !s)) : (s = x, (a || !x) && (x = "error", 0 > a && (a = 0))), v.status = a, v.statusText = (b || x) + "", j ? o.resolveWith(l, [r, x, v]) : o.rejectWith(l, [v, x, s]), v.statusCode(q), q = void 0, h && m.trigger(j ? "ajaxSuccess" : "ajaxError", [v, k, j ? r : s]), p.fireWith(l, [v, x]), h && (m.trigger("ajaxComplete", [v, k]), --n.active || n.event.trigger("ajaxStop")))
                }
                return v
            },
            getJSON: function(a, b, c) {
                return n.get(a, b, c, "json")
            },
            getScript: function(a, b) {
                return n.get(a, void 0, b, "script")
            }
        }), n.each(["get", "post"], function(a, b) {
            n[b] = function(a, c, d, e) {
                return n.isFunction(c) && (e = e || d, d = c, c = void 0), n.ajax({
                    url: a,
                    type: b,
                    dataType: e,
                    data: c,
                    success: d
                })
            }
        }), n.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function(a, b) {
            n.fn[b] = function(a) {
                return this.on(b, a)
            }
        }), n._evalUrl = function(a) {
            return n.ajax({
                url: a,
                type: "GET",
                dataType: "script",
                async: !1,
                global: !1,
                "throws": !0
            })
        }, n.fn.extend({
            wrapAll: function(a) {
                if (n.isFunction(a)) return this.each(function(b) {
                    n(this).wrapAll(a.call(this, b))
                });
                if (this[0]) {
                    var b = n(a, this[0].ownerDocument).eq(0).clone(!0);
                    this[0].parentNode && b.insertBefore(this[0]), b.map(function() {
                        var a = this;
                        while (a.firstChild && 1 === a.firstChild.nodeType) a = a.firstChild;
                        return a
                    }).append(this)
                }
                return this
            },
            wrapInner: function(a) {
                return this.each(n.isFunction(a) ? function(b) {
                    n(this).wrapInner(a.call(this, b))
                } : function() {
                    var b = n(this),
                        c = b.contents();
                    c.length ? c.wrapAll(a) : b.append(a)
                })
            },
            wrap: function(a) {
                var b = n.isFunction(a);
                return this.each(function(c) {
                    n(this).wrapAll(b ? a.call(this, c) : a)
                })
            },
            unwrap: function() {
                return this.parent().each(function() {
                    n.nodeName(this, "body") || n(this).replaceWith(this.childNodes)
                }).end()
            }
        }), n.expr.filters.hidden = function(a) {
            return a.offsetWidth <= 0 && a.offsetHeight <= 0 || !l.reliableHiddenOffsets() && "none" === (a.style && a.style.display || n.css(a, "display"))
        }, n.expr.filters.visible = function(a) {
            return !n.expr.filters.hidden(a)
        };
        var Rc = /%20/g,
            Sc = /\[\]$/,
            Tc = /\r?\n/g,
            Uc = /^(?:submit|button|image|reset|file)$/i,
            Vc = /^(?:input|select|textarea|keygen)/i;
    
        function Wc(a, b, c, d) {
            var e;
            if (n.isArray(b)) n.each(b, function(b, e) {
                c || Sc.test(a) ? d(a, e) : Wc(a + "[" + ("object" == typeof e ? b : "") + "]", e, c, d)
            });
            else if (c || "object" !== n.type(b)) d(a, b);
            else
                for (e in b) Wc(a + "[" + e + "]", b[e], c, d)
        }
        n.param = function(a, b) {
            var c, d = [],
                e = function(a, b) {
                    b = n.isFunction(b) ? b() : null == b ? "" : b, d[d.length] = encodeURIComponent(a) + "=" + encodeURIComponent(b)
                };
            if (void 0 === b && (b = n.ajaxSettings && n.ajaxSettings.traditional), n.isArray(a) || a.jquery && !n.isPlainObject(a)) n.each(a, function() {
                e(this.name, this.value)
            });
            else
                for (c in a) Wc(c, a[c], b, e);
            return d.join("&").replace(Rc, "+")
        }, n.fn.extend({
            serialize: function() {
                return n.param(this.serializeArray())
            },
            serializeArray: function() {
                return this.map(function() {
                    var a = n.prop(this, "elements");
                    return a ? n.makeArray(a) : this
                }).filter(function() {
                    var a = this.type;
                    return this.name && !n(this).is(":disabled") && Vc.test(this.nodeName) && !Uc.test(a) && (this.checked || !X.test(a))
                }).map(function(a, b) {
                    var c = n(this).val();
                    return null == c ? null : n.isArray(c) ? n.map(c, function(a) {
                        return {
                            name: b.name,
                            value: a.replace(Tc, "\r\n")
                        }
                    }) : {
                        name: b.name,
                        value: c.replace(Tc, "\r\n")
                    }
                }).get()
            }
        }), n.ajaxSettings.xhr = void 0 !== a.ActiveXObject ? function() {
            return !this.isLocal && /^(get|post|head|put|delete|options)$/i.test(this.type) && $c() || _c()
        } : $c;
        var Xc = 0,
            Yc = {},
            Zc = n.ajaxSettings.xhr();
        a.ActiveXObject && n(a).on("unload", function() {
            for (var a in Yc) Yc[a](void 0, !0)
        }), l.cors = !!Zc && "withCredentials" in Zc, Zc = l.ajax = !!Zc, Zc && n.ajaxTransport(function(a) {
            if (!a.crossDomain || l.cors) {
                var b;
                return {
                    send: function(c, d) {
                        var e, f = a.xhr(),
                            g = ++Xc;
                        if (f.open(a.type, a.url, a.async, a.username, a.password), a.xhrFields)
                            for (e in a.xhrFields) f[e] = a.xhrFields[e];
                        a.mimeType && f.overrideMimeType && f.overrideMimeType(a.mimeType), a.crossDomain || c["X-Requested-With"] || (c["X-Requested-With"] = "XMLHttpRequest");
                        for (e in c) void 0 !== c[e] && f.setRequestHeader(e, c[e] + "");
                        f.send(a.hasContent && a.data || null), b = function(c, e) {
                            var h, i, j;
                            if (b && (e || 4 === f.readyState))
                                if (delete Yc[g], b = void 0, f.onreadystatechange = n.noop, e) 4 !== f.readyState && f.abort();
                                else {
                                    j = {}, h = f.status, "string" == typeof f.responseText && (j.text = f.responseText);
                                    try {
                                        i = f.statusText
                                    } catch (k) {
                                        i = ""
                                    }
                                    h || !a.isLocal || a.crossDomain ? 1223 === h && (h = 204) : h = j.text ? 200 : 404
                                }
                            j && d(h, i, j, f.getAllResponseHeaders())
                        }, a.async ? 4 === f.readyState ? setTimeout(b) : f.onreadystatechange = Yc[g] = b : b()
                    },
                    abort: function() {
                        b && b(void 0, !0)
                    }
                }
            }
        });
    
        function $c() {
            try {
                return new a.XMLHttpRequest
            } catch (b) {}
        }
    
        function _c() {
            try {
                return new a.ActiveXObject("Microsoft.XMLHTTP")
            } catch (b) {}
        }
        n.ajaxSetup({
            accepts: {
                script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
            },
            contents: {
                script: /(?:java|ecma)script/
            },
            converters: {
                "text script": function(a) {
                    return n.globalEval(a), a
                }
            }
        }), n.ajaxPrefilter("script", function(a) {
            void 0 === a.cache && (a.cache = !1), a.crossDomain && (a.type = "GET", a.global = !1)
        }), n.ajaxTransport("script", function(a) {
            if (a.crossDomain) {
                var b, c = z.head || n("head")[0] || z.documentElement;
                return {
                    send: function(d, e) {
                        b = z.createElement("script"), b.async = !0, a.scriptCharset && (b.charset = a.scriptCharset), b.src = a.url, b.onload = b.onreadystatechange = function(a, c) {
                            (c || !b.readyState || /loaded|complete/.test(b.readyState)) && (b.onload = b.onreadystatechange = null, b.parentNode && b.parentNode.removeChild(b), b = null, c || e(200, "success"))
                        }, c.insertBefore(b, c.firstChild)
                    },
                    abort: function() {
                        b && b.onload(void 0, !0)
                    }
                }
            }
        });
        var ad = [],
            bd = /(=)\?(?=&|$)|\?\?/;
        n.ajaxSetup({
            jsonp: "callback",
            jsonpCallback: function() {
                var a = ad.pop() || n.expando + "_" + wc++;
                return this[a] = !0, a
            }
        }), n.ajaxPrefilter("json jsonp", function(b, c, d) {
            var e, f, g, h = b.jsonp !== !1 && (bd.test(b.url) ? "url" : "string" == typeof b.data && !(b.contentType || "").indexOf("application/x-www-form-urlencoded") && bd.test(b.data) && "data");
            return h || "jsonp" === b.dataTypes[0] ? (e = b.jsonpCallback = n.isFunction(b.jsonpCallback) ? b.jsonpCallback() : b.jsonpCallback, h ? b[h] = b[h].replace(bd, "$1" + e) : b.jsonp !== !1 && (b.url += (xc.test(b.url) ? "&" : "?") + b.jsonp + "=" + e), b.converters["script json"] = function() {
                return g || n.error(e + " was not called"), g[0]
            }, b.dataTypes[0] = "json", f = a[e], a[e] = function() {
                g = arguments
            }, d.always(function() {
                a[e] = f, b[e] && (b.jsonpCallback = c.jsonpCallback, ad.push(e)), g && n.isFunction(f) && f(g[0]), g = f = void 0
            }), "script") : void 0
        }), n.parseHTML = function(a, b, c) {
            if (!a || "string" != typeof a) return null;
            "boolean" == typeof b && (c = b, b = !1), b = b || z;
            var d = v.exec(a),
                e = !c && [];
            return d ? [b.createElement(d[1])] : (d = n.buildFragment([a], b, e), e && e.length && n(e).remove(), n.merge([], d.childNodes))
        };
        var cd = n.fn.load;
        n.fn.load = function(a, b, c) {
            if ("string" != typeof a && cd) return cd.apply(this, arguments);
            var d, e, f, g = this,
                h = a.indexOf(" ");
            return h >= 0 && (d = a.slice(h, a.length), a = a.slice(0, h)), n.isFunction(b) ? (c = b, b = void 0) : b && "object" == typeof b && (f = "POST"), g.length > 0 && n.ajax({
                url: a,
                type: f,
                dataType: "html",
                data: b
            }).done(function(a) {
                e = arguments, g.html(d ? n("<div>").append(n.parseHTML(a)).find(d) : a)
            }).complete(c && function(a, b) {
                g.each(c, e || [a.responseText, b, a])
            }), this
        }, n.expr.filters.animated = function(a) {
            return n.grep(n.timers, function(b) {
                return a === b.elem
            }).length
        };
        var dd = a.document.documentElement;
    
        function ed(a) {
            return n.isWindow(a) ? a : 9 === a.nodeType ? a.defaultView || a.parentWindow : !1
        }
        n.offset = {
            setOffset: function(a, b, c) {
                var d, e, f, g, h, i, j, k = n.css(a, "position"),
                    l = n(a),
                    m = {};
                "static" === k && (a.style.position = "relative"), h = l.offset(), f = n.css(a, "top"), i = n.css(a, "left"), j = ("absolute" === k || "fixed" === k) && n.inArray("auto", [f, i]) > -1, j ? (d = l.position(), g = d.top, e = d.left) : (g = parseFloat(f) || 0, e = parseFloat(i) || 0), n.isFunction(b) && (b = b.call(a, c, h)), null != b.top && (m.top = b.top - h.top + g), null != b.left && (m.left = b.left - h.left + e), "using" in b ? b.using.call(a, m) : l.css(m)
            }
        }, n.fn.extend({
            offset: function(a) {
                if (arguments.length) return void 0 === a ? this : this.each(function(b) {
                    n.offset.setOffset(this, a, b)
                });
                var b, c, d = {
                        top: 0,
                        left: 0
                    },
                    e = this[0],
                    f = e && e.ownerDocument;
                if (f) return b = f.documentElement, n.contains(b, e) ? (typeof e.getBoundingClientRect !== L && (d = e.getBoundingClientRect()), c = ed(f), {
                    top: d.top + (c.pageYOffset || b.scrollTop) - (b.clientTop || 0),
                    left: d.left + (c.pageXOffset || b.scrollLeft) - (b.clientLeft || 0)
                }) : d
            },
            position: function() {
                if (this[0]) {
                    var a, b, c = {
                            top: 0,
                            left: 0
                        },
                        d = this[0];
                    return "fixed" === n.css(d, "position") ? b = d.getBoundingClientRect() : (a = this.offsetParent(), b = this.offset(), n.nodeName(a[0], "html") || (c = a.offset()), c.top += n.css(a[0], "borderTopWidth", !0), c.left += n.css(a[0], "borderLeftWidth", !0)), {
                        top: b.top - c.top - n.css(d, "marginTop", !0),
                        left: b.left - c.left - n.css(d, "marginLeft", !0)
                    }
                }
            },
            offsetParent: function() {
                return this.map(function() {
                    var a = this.offsetParent || dd;
                    while (a && !n.nodeName(a, "html") && "static" === n.css(a, "position")) a = a.offsetParent;
                    return a || dd
                })
            }
        }), n.each({
            scrollLeft: "pageXOffset",
            scrollTop: "pageYOffset"
        }, function(a, b) {
            var c = /Y/.test(b);
            n.fn[a] = function(d) {
                return W(this, function(a, d, e) {
                    var f = ed(a);
                    return void 0 === e ? f ? b in f ? f[b] : f.document.documentElement[d] : a[d] : void(f ? f.scrollTo(c ? n(f).scrollLeft() : e, c ? e : n(f).scrollTop()) : a[d] = e)
                }, a, d, arguments.length, null)
            }
        }), n.each(["top", "left"], function(a, b) {
            n.cssHooks[b] = Mb(l.pixelPosition, function(a, c) {
                return c ? (c = Kb(a, b), Ib.test(c) ? n(a).position()[b] + "px" : c) : void 0
            })
        }), n.each({
            Height: "height",
            Width: "width"
        }, function(a, b) {
            n.each({
                padding: "inner" + a,
                content: b,
                "": "outer" + a
            }, function(c, d) {
                n.fn[d] = function(d, e) {
                    var f = arguments.length && (c || "boolean" != typeof d),
                        g = c || (d === !0 || e === !0 ? "margin" : "border");
                    return W(this, function(b, c, d) {
                        var e;
                        return n.isWindow(b) ? b.document.documentElement["client" + a] : 9 === b.nodeType ? (e = b.documentElement, Math.max(b.body["scroll" + a], e["scroll" + a], b.body["offset" + a], e["offset" + a], e["client" + a])) : void 0 === d ? n.css(b, c, g) : n.style(b, c, d, g)
                    }, b, f ? d : void 0, f, null)
                }
            })
        }), n.fn.size = function() {
            return this.length
        }, n.fn.andSelf = n.fn.addBack, "function" == typeof define && define.amd && define("jquery", [], function() {
            return n
        });
        var fd = a.jQuery,
            gd = a.$;
        return n.noConflict = function(b) {
            return a.$ === n && (a.$ = gd), b && a.jQuery === n && (a.jQuery = fd), n
        }, typeof b === L && (a.jQuery = a.$ = n), n
    });
    /*! RESOURCE: /scripts/thirdparty/cometd/jquery/jquery-1.11.0_no_conflict.js */
    (function() {
        window.jQuery1110 = jQuery.noConflict(true);
    })();;
    /*! RESOURCE: /scripts/thirdparty/cometd/org/cometd.js */
    this.org = this.org || {};
    org.cometd = {};
    org.cometd.JSON = {};
    org.cometd.JSON.toJSON = org.cometd.JSON.fromJSON = function(object) {
        throw 'Abstract';
    };
    org.cometd.Utils = {};
    org.cometd.Utils.isString = function(value) {
        if (value === undefined || value === null) {
            return false;
        }
        return typeof value === 'string' || value instanceof String;
    };
    org.cometd.Utils.isArray = function(value) {
        if (value === undefined || value === null) {
            return false;
        }
        return value instanceof Array;
    };
    org.cometd.Utils.inArray = function(element, array) {
        for (var i = 0; i < array.length; ++i) {
            if (element === array[i]) {
                return i;
            }
        }
        return -1;
    };
    org.cometd.Utils.setTimeout = function(cometd, funktion, delay) {
        return window.setTimeout(function() {
            try {
                funktion();
            } catch (x) {
                cometd._debug('Exception invoking timed function', funktion, x);
            }
        }, delay);
    };
    org.cometd.Utils.clearTimeout = function(timeoutHandle) {
        window.clearTimeout(timeoutHandle);
    };
    org.cometd.TransportRegistry = function() {
        var _types = [];
        var _transports = {};
        this.getTransportTypes = function() {
            return _types.slice(0);
        };
        this.findTransportTypes = function(version, crossDomain, url) {
            var result = [];
            for (var i = 0; i < _types.length; ++i) {
                var type = _types[i];
                if (_transports[type].accept(version, crossDomain, url) === true) {
                    result.push(type);
                }
            }
            return result;
        };
        this.negotiateTransport = function(types, version, crossDomain, url) {
            for (var i = 0; i < _types.length; ++i) {
                var type = _types[i];
                for (var j = 0; j < types.length; ++j) {
                    if (type === types[j]) {
                        var transport = _transports[type];
                        if (transport.accept(version, crossDomain, url) === true) {
                            return transport;
                        }
                    }
                }
            }
            return null;
        };
        this.add = function(type, transport, index) {
            var existing = false;
            for (var i = 0; i < _types.length; ++i) {
                if (_types[i] === type) {
                    existing = true;
                    break;
                }
            }
            if (!existing) {
                if (typeof index !== 'number') {
                    _types.push(type);
                } else {
                    _types.splice(index, 0, type);
                }
                _transports[type] = transport;
            }
            return !existing;
        };
        this.find = function(type) {
            for (var i = 0; i < _types.length; ++i) {
                if (_types[i] === type) {
                    return _transports[type];
                }
            }
            return null;
        };
        this.remove = function(type) {
            for (var i = 0; i < _types.length; ++i) {
                if (_types[i] === type) {
                    _types.splice(i, 1);
                    var transport = _transports[type];
                    delete _transports[type];
                    return transport;
                }
            }
            return null;
        };
        this.clear = function() {
            _types = [];
            _transports = {};
        };
        this.reset = function() {
            for (var i = 0; i < _types.length; ++i) {
                _transports[_types[i]].reset();
            }
        };
    };
    org.cometd.Transport = function() {
        var _type;
        var _cometd;
        this.registered = function(type, cometd) {
            _type = type;
            _cometd = cometd;
        };
        this.unregistered = function() {
            _type = null;
            _cometd = null;
        };
        this._debug = function() {
            _cometd._debug.apply(_cometd, arguments);
        };
        this._mixin = function() {
            return _cometd._mixin.apply(_cometd, arguments);
        };
        this.getConfiguration = function() {
            return _cometd.getConfiguration();
        };
        this.getAdvice = function() {
            return _cometd.getAdvice();
        };
        this.setTimeout = function(funktion, delay) {
            return org.cometd.Utils.setTimeout(_cometd, funktion, delay);
        };
        this.clearTimeout = function(handle) {
            org.cometd.Utils.clearTimeout(handle);
        };
        this.convertToMessages = function(response) {
            if (org.cometd.Utils.isString(response)) {
                try {
                    return org.cometd.JSON.fromJSON(response);
                } catch (x) {
                    this._debug('Could not convert to JSON the following string', '"' + response + '"');
                    throw x;
                }
            }
            if (org.cometd.Utils.isArray(response)) {
                return response;
            }
            if (response === undefined || response === null) {
                return [];
            }
            if (response instanceof Object) {
                return [response];
            }
            throw 'Conversion Error ' + response + ', typeof ' + (typeof response);
        };
        this.accept = function(version, crossDomain, url) {
            throw 'Abstract';
        };
        this.getType = function() {
            return _type;
        };
        this.send = function(envelope, metaConnect) {
            throw 'Abstract';
        };
        this.reset = function() {
            this._debug('Transport', _type, 'reset');
        };
        this.abort = function() {
            this._debug('Transport', _type, 'aborted');
        };
        this.toString = function() {
            return this.getType();
        };
    };
    org.cometd.Transport.derive = function(baseObject) {
        function F() {}
        F.prototype = baseObject;
        return new F();
    };
    org.cometd.RequestTransport = function() {
        var _super = new org.cometd.Transport();
        var _self = org.cometd.Transport.derive(_super);
        var _requestIds = 0;
        var _metaConnectRequest = null;
        var _requests = [];
        var _envelopes = [];
    
        function _coalesceEnvelopes(envelope) {
            while (_envelopes.length > 0) {
                var envelopeAndRequest = _envelopes[0];
                var newEnvelope = envelopeAndRequest[0];
                var newRequest = envelopeAndRequest[1];
                if (newEnvelope.url === envelope.url &&
                    newEnvelope.sync === envelope.sync) {
                    _envelopes.shift();
                    envelope.messages = envelope.messages.concat(newEnvelope.messages);
                    this._debug('Coalesced', newEnvelope.messages.length, 'messages from request', newRequest.id);
                    continue;
                }
                break;
            }
        }
    
        function _transportSend(envelope, request) {
            this.transportSend(envelope, request);
            request.expired = false;
            if (!envelope.sync) {
                var maxDelay = this.getConfiguration().maxNetworkDelay;
                var delay = maxDelay;
                if (request.metaConnect === true) {
                    delay += this.getAdvice().timeout;
                }
                this._debug('Transport', this.getType(), 'waiting at most', delay, 'ms for the response, maxNetworkDelay', maxDelay);
                var self = this;
                request.timeout = this.setTimeout(function() {
                    request.expired = true;
                    var errorMessage = 'Request ' + request.id + ' of transport ' + self.getType() + ' exceeded ' + delay + ' ms max network delay';
                    var failure = {
                        reason: errorMessage
                    };
                    var xhr = request.xhr;
                    failure.httpCode = self.xhrStatus(xhr);
                    self.abortXHR(xhr);
                    self._debug(errorMessage);
                    self.complete(request, false, request.metaConnect);
                    envelope.onFailure(xhr, envelope.messages, failure);
                }, delay);
            }
        }
    
        function _queueSend(envelope) {
            var requestId = ++_requestIds;
            var request = {
                id: requestId,
                metaConnect: false
            };
            if (_requests.length < this.getConfiguration().maxConnections - 1) {
                _requests.push(request);
                _transportSend.call(this, envelope, request);
            } else {
                this._debug('Transport', this.getType(), 'queueing request', requestId, 'envelope', envelope);
                _envelopes.push([envelope, request]);
            }
        }
    
        function _metaConnectComplete(request) {
            var requestId = request.id;
            this._debug('Transport', this.getType(), 'metaConnect complete, request', requestId);
            if (_metaConnectRequest !== null && _metaConnectRequest.id !== requestId) {
                throw 'Longpoll request mismatch, completing request ' + requestId;
            }
            _metaConnectRequest = null;
        }
    
        function _complete(request, success) {
            var index = org.cometd.Utils.inArray(request, _requests);
            if (index >= 0) {
                _requests.splice(index, 1);
            }
            if (_envelopes.length > 0) {
                var envelopeAndRequest = _envelopes.shift();
                var nextEnvelope = envelopeAndRequest[0];
                var nextRequest = envelopeAndRequest[1];
                this._debug('Transport dequeued request', nextRequest.id);
                if (success) {
                    if (this.getConfiguration().autoBatch) {
                        _coalesceEnvelopes.call(this, nextEnvelope);
                    }
                    _queueSend.call(this, nextEnvelope);
                    this._debug('Transport completed request', request.id, nextEnvelope);
                } else {
                    var self = this;
                    this.setTimeout(function() {
                        self.complete(nextRequest, false, nextRequest.metaConnect);
                        var failure = {
                            reason: 'Previous request failed'
                        };
                        var xhr = nextRequest.xhr;
                        failure.httpCode = self.xhrStatus(xhr);
                        nextEnvelope.onFailure(xhr, nextEnvelope.messages, failure);
                    }, 0);
                }
            }
        }
        _self.complete = function(request, success, metaConnect) {
            if (metaConnect) {
                _metaConnectComplete.call(this, request);
            } else {
                _complete.call(this, request, success);
            }
        };
        _self.transportSend = function(envelope, request) {
            throw 'Abstract';
        };
        _self.transportSuccess = function(envelope, request, responses) {
            if (!request.expired) {
                this.clearTimeout(request.timeout);
                this.complete(request, true, request.metaConnect);
                if (responses && responses.length > 0) {
                    envelope.onSuccess(responses);
                } else {
                    envelope.onFailure(request.xhr, envelope.messages, {
                        httpCode: 204
                    });
                }
            }
        };
        _self.transportFailure = function(envelope, request, failure) {
            if (!request.expired) {
                this.clearTimeout(request.timeout);
                this.complete(request, false, request.metaConnect);
                envelope.onFailure(request.xhr, envelope.messages, failure);
            }
        };
    
        function _metaConnectSend(envelope) {
            if (_metaConnectRequest !== null) {
                throw 'Concurrent metaConnect requests not allowed, request id=' + _metaConnectRequest.id + ' not yet completed';
            }
            var requestId = ++_requestIds;
            this._debug('Transport', this.getType(), 'metaConnect send, request', requestId, 'envelope', envelope);
            var request = {
                id: requestId,
                metaConnect: true
            };
            _transportSend.call(this, envelope, request);
            _metaConnectRequest = request;
        }
        _self.send = function(envelope, metaConnect) {
            if (metaConnect) {
                _metaConnectSend.call(this, envelope);
            } else {
                _queueSend.call(this, envelope);
            }
        };
        _self.abort = function() {
            _super.abort();
            for (var i = 0; i < _requests.length; ++i) {
                var request = _requests[i];
                this._debug('Aborting request', request);
                this.abortXHR(request.xhr);
            }
            if (_metaConnectRequest) {
                this._debug('Aborting metaConnect request', _metaConnectRequest);
                this.abortXHR(_metaConnectRequest.xhr);
            }
            this.reset();
        };
        _self.reset = function() {
            _super.reset();
            _metaConnectRequest = null;
            _requests = [];
            _envelopes = [];
        };
        _self.abortXHR = function(xhr) {
            if (xhr) {
                try {
                    xhr.abort();
                } catch (x) {
                    this._debug(x);
                }
            }
        };
        _self.xhrStatus = function(xhr) {
            if (xhr) {
                try {
                    return xhr.status;
                } catch (x) {
                    this._debug(x);
                }
            }
            return -1;
        };
        return _self;
    };
    org.cometd.LongPollingTransport = function() {
        var _super = new org.cometd.RequestTransport();
        var _self = org.cometd.Transport.derive(_super);
        var _supportsCrossDomain = true;
        _self.accept = function(version, crossDomain, url) {
            return _supportsCrossDomain || !crossDomain;
        };
        _self.xhrSend = function(packet) {
            throw 'Abstract';
        };
        _self.transportSend = function(envelope, request) {
            this._debug('Transport', this.getType(), 'sending request', request.id, 'envelope', envelope);
            var self = this;
            try {
                var sameStack = true;
                request.xhr = this.xhrSend({
                    transport: this,
                    url: envelope.url,
                    sync: envelope.sync,
                    headers: this.getConfiguration().requestHeaders,
                    body: org.cometd.JSON.toJSON(envelope.messages),
                    onSuccess: function(response) {
                        self._debug('Transport', self.getType(), 'received response', response);
                        var success = false;
                        try {
                            var received = self.convertToMessages(response);
                            if (received.length === 0) {
                                _supportsCrossDomain = false;
                                self.transportFailure(envelope, request, {
                                    httpCode: 204
                                });
                            } else {
                                success = true;
                                self.transportSuccess(envelope, request, received);
                            }
                        } catch (x) {
                            self._debug(x);
                            if (!success) {
                                _supportsCrossDomain = false;
                                var failure = {
                                    exception: x
                                };
                                failure.httpCode = self.xhrStatus(request.xhr);
                                self.transportFailure(envelope, request, failure);
                            }
                        }
                    },
                    onError: function(reason, exception) {
                        _supportsCrossDomain = false;
                        var failure = {
                            reason: reason,
                            exception: exception
                        };
                        failure.httpCode = self.xhrStatus(request.xhr);
                        if (sameStack) {
                            self.setTimeout(function() {
                                self.transportFailure(envelope, request, failure);
                            }, 0);
                        } else {
                            self.transportFailure(envelope, request, failure);
                        }
                    }
                });
                sameStack = false;
            } catch (x) {
                _supportsCrossDomain = false;
                this.setTimeout(function() {
                    self.transportFailure(envelope, request, {
                        exception: x
                    });
                }, 0);
            }
        };
        _self.reset = function() {
            _super.reset();
            _supportsCrossDomain = true;
        };
        return _self;
    };
    org.cometd.CallbackPollingTransport = function() {
        var _super = new org.cometd.RequestTransport();
        var _self = org.cometd.Transport.derive(_super);
        var _maxLength = 2000;
        _self.accept = function(version, crossDomain, url) {
            return true;
        };
        _self.jsonpSend = function(packet) {
            throw 'Abstract';
        };
        _self.transportSend = function(envelope, request) {
            var self = this;
            var start = 0;
            var length = envelope.messages.length;
            var lengths = [];
            while (length > 0) {
                var json = org.cometd.JSON.toJSON(envelope.messages.slice(start, start + length));
                var urlLength = envelope.url.length + encodeURI(json).length;
                if (urlLength > _maxLength) {
                    if (length === 1) {
                        this.setTimeout(function() {
                            self.transportFailure(envelope, request, {
                                reason: 'Bayeux message too big, max is ' + _maxLength
                            });
                        }, 0);
                        return;
                    }
                    --length;
                    continue;
                }
                lengths.push(length);
                start += length;
                length = envelope.messages.length - start;
            }
            var envelopeToSend = envelope;
            if (lengths.length > 1) {
                var begin = 0;
                var end = lengths[0];
                this._debug('Transport', this.getType(), 'split', envelope.messages.length, 'messages into', lengths.join(' + '));
                envelopeToSend = this._mixin(false, {}, envelope);
                envelopeToSend.messages = envelope.messages.slice(begin, end);
                envelopeToSend.onSuccess = envelope.onSuccess;
                envelopeToSend.onFailure = envelope.onFailure;
                for (var i = 1; i < lengths.length; ++i) {
                    var nextEnvelope = this._mixin(false, {}, envelope);
                    begin = end;
                    end += lengths[i];
                    nextEnvelope.messages = envelope.messages.slice(begin, end);
                    nextEnvelope.onSuccess = envelope.onSuccess;
                    nextEnvelope.onFailure = envelope.onFailure;
                    this.send(nextEnvelope, request.metaConnect);
                }
            }
            this._debug('Transport', this.getType(), 'sending request', request.id, 'envelope', envelopeToSend);
            try {
                var sameStack = true;
                this.jsonpSend({
                    transport: this,
                    url: envelopeToSend.url,
                    sync: envelopeToSend.sync,
                    headers: this.getConfiguration().requestHeaders,
                    body: org.cometd.JSON.toJSON(envelopeToSend.messages),
                    onSuccess: function(responses) {
                        var success = false;
                        try {
                            var received = self.convertToMessages(responses);
                            if (received.length === 0) {
                                self.transportFailure(envelopeToSend, request, {
                                    httpCode: 204
                                });
                            } else {
                                success = true;
                                self.transportSuccess(envelopeToSend, request, received);
                            }
                        } catch (x) {
                            self._debug(x);
                            if (!success) {
                                self.transportFailure(envelopeToSend, request, {
                                    exception: x
                                });
                            }
                        }
                    },
                    onError: function(reason, exception) {
                        var failure = {
                            reason: reason,
                            exception: exception
                        };
                        if (sameStack) {
                            self.setTimeout(function() {
                                self.transportFailure(envelopeToSend, request, failure);
                            }, 0);
                        } else {
                            self.transportFailure(envelopeToSend, request, failure);
                        }
                    }
                });
                sameStack = false;
            } catch (xx) {
                this.setTimeout(function() {
                    self.transportFailure(envelopeToSend, request, {
                        exception: xx
                    });
                }, 0);
            }
        };
        return _self;
    };
    org.cometd.WebSocketTransport = function() {
        var _super = new org.cometd.Transport();
        var _self = org.cometd.Transport.derive(_super);
        var _cometd;
        var _webSocketSupported = true;
        var _webSocketConnected = false;
        var _stickyReconnect = true;
        var _envelopes = {};
        var _timeouts = {};
        var _connecting = false;
        var _webSocket = null;
        var _connected = false;
        var _successCallback = null;
        _self.reset = function() {
            _super.reset();
            _webSocketSupported = true;
            _webSocketConnected = false;
            _stickyReconnect = true;
            _envelopes = {};
            _timeouts = {};
            _connecting = false;
            _webSocket = null;
            _connected = false;
            _successCallback = null;
        };
    
        function _websocketConnect() {
            if (_connecting) {
                return;
            }
            _connecting = true;
            var url = _cometd.getURL().replace(/^http/, 'ws');
            this._debug('Transport', this.getType(), 'connecting to URL', url);
            try {
                var protocol = _cometd.getConfiguration().protocol;
                var webSocket = protocol ? new org.cometd.WebSocket(url, protocol) : new org.cometd.WebSocket(url);
            } catch (x) {
                _webSocketSupported = false;
                this._debug('Exception while creating WebSocket object', x);
                throw x;
            }
            _stickyReconnect = _cometd.getConfiguration().stickyReconnect !== false;
            var self = this;
            var connectTimer = null;
            var connectTimeout = _cometd.getConfiguration().connectTimeout;
            if (connectTimeout > 0) {
                connectTimer = this.setTimeout(function() {
                    connectTimer = null;
                    self._debug('Transport', self.getType(), 'timed out while connecting to URL', url, ':', connectTimeout, 'ms');
                    var event = {
                        code: 1000,
                        reason: 'Connect Timeout'
                    };
                    self.webSocketClose(webSocket, event.code, event.reason);
                    self.onClose(webSocket, event);
                }, connectTimeout);
            }
            var onopen = function() {
                self._debug('WebSocket opened', webSocket);
                _connecting = false;
                if (connectTimer) {
                    self.clearTimeout(connectTimer);
                    connectTimer = null;
                }
                if (_webSocket) {
                    _cometd._warn('Closing Extra WebSocket Connections', webSocket, _webSocket);
                    self.webSocketClose(webSocket, 1000, 'Extra Connection');
                } else {
                    self.onOpen(webSocket);
                }
            };
            var onclose = function(event) {
                event = event || {
                    code: 1000
                };
                self._debug('WebSocket closing', webSocket, event);
                _connecting = false;
                if (connectTimer) {
                    self.clearTimeout(connectTimer);
                    connectTimer = null;
                }
                if (_webSocket !== null && webSocket !== _webSocket) {
                    self._debug('Closed Extra WebSocket Connection', webSocket);
                } else {
                    self.onClose(webSocket, event);
                }
            };
            var onmessage = function(message) {
                self._debug('WebSocket message', message, webSocket);
                if (webSocket !== _webSocket) {
                    _cometd._warn('Extra WebSocket Connections', webSocket, _webSocket);
                }
                self.onMessage(webSocket, message);
            };
            webSocket.onopen = onopen;
            webSocket.onclose = onclose;
            webSocket.onerror = function() {
                onclose({
                    code: 1002,
                    reason: 'Error'
                });
            };
            webSocket.onmessage = onmessage;
            this._debug('Transport', this.getType(), 'configured callbacks on', webSocket);
        }
    
        function _webSocketSend(webSocket, envelope, metaConnect) {
            var json = org.cometd.JSON.toJSON(envelope.messages);
            webSocket.send(json);
            this._debug('Transport', this.getType(), 'sent', envelope, 'metaConnect =', metaConnect);
            var maxDelay = this.getConfiguration().maxNetworkDelay;
            var delay = maxDelay;
            if (metaConnect) {
                delay += this.getAdvice().timeout;
                _connected = true;
            }
            var self = this;
            var messageIds = [];
            for (var i = 0; i < envelope.messages.length; ++i) {
                (function() {
                    var message = envelope.messages[i];
                    if (message.id) {
                        messageIds.push(message.id);
                        _timeouts[message.id] = this.setTimeout(function() {
                            self._debug('Transport', self.getType(), 'timing out message', message.id, 'after', delay, 'on', webSocket);
                            var event = {
                                code: 1000,
                                reason: 'Message Timeout'
                            };
                            self.webSocketClose(webSocket, event.code, event.reason);
                            self.onClose(webSocket, event);
                        }, delay);
                    }
                })();
            }
            this._debug('Transport', this.getType(), 'waiting at most', delay, 'ms for messages', messageIds, 'maxNetworkDelay', maxDelay, ', timeouts:', _timeouts);
        }
    
        function _send(webSocket, envelope, metaConnect) {
            try {
                if (webSocket === null) {
                    _websocketConnect.call(this);
                } else {
                    _webSocketSend.call(this, webSocket, envelope, metaConnect);
                }
            } catch (x) {
                this.setTimeout(function() {
                    envelope.onFailure(webSocket, envelope.messages, {
                        exception: x
                    });
                }, 0);
            }
        }
        _self.onOpen = function(webSocket) {
            this._debug('Transport', this.getType(), 'opened', webSocket);
            _webSocket = webSocket;
            _webSocketConnected = true;
            this._debug('Sending pending messages', _envelopes);
            for (var key in _envelopes) {
                var element = _envelopes[key];
                var envelope = element[0];
                var metaConnect = element[1];
                _successCallback = envelope.onSuccess;
                _webSocketSend.call(this, webSocket, envelope, metaConnect);
            }
        };
        _self.onMessage = function(webSocket, wsMessage) {
            this._debug('Transport', this.getType(), 'received websocket message', wsMessage, webSocket);
            var close = false;
            var messages = this.convertToMessages(wsMessage.data);
            var messageIds = [];
            for (var i = 0; i < messages.length; ++i) {
                var message = messages[i];
                if (/^\/meta\//.test(message.channel) || message.successful !== undefined) {
                    if (message.id) {
                        messageIds.push(message.id);
                        var timeout = _timeouts[message.id];
                        if (timeout) {
                            this.clearTimeout(timeout);
                            delete _timeouts[message.id];
                            this._debug('Transport', this.getType(), 'removed timeout for message', message.id, ', timeouts', _timeouts);
                        }
                    }
                }
                if ('/meta/connect' === message.channel) {
                    _connected = false;
                }
                if ('/meta/disconnect' === message.channel && !_connected) {
                    close = true;
                }
            }
            var removed = false;
            for (var j = 0; j < messageIds.length; ++j) {
                var id = messageIds[j];
                for (var key in _envelopes) {
                    var ids = key.split(',');
                    var index = org.cometd.Utils.inArray(id, ids);
                    if (index >= 0) {
                        removed = true;
                        ids.splice(index, 1);
                        var envelope = _envelopes[key][0];
                        var metaConnect = _envelopes[key][1];
                        delete _envelopes[key];
                        if (ids.length > 0) {
                            _envelopes[ids.join(',')] = [envelope, metaConnect];
                        }
                        break;
                    }
                }
            }
            if (removed) {
                this._debug('Transport', this.getType(), 'removed envelope, envelopes', _envelopes);
            }
            _successCallback.call(this, messages);
            if (close) {
                this.webSocketClose(webSocket, 1000, 'Disconnect');
            }
        };
        _self.onClose = function(webSocket, event) {
            this._debug('Transport', this.getType(), 'closed', webSocket, event);
            _webSocketSupported = _stickyReconnect && _webSocketConnected;
            for (var id in _timeouts) {
                this.clearTimeout(_timeouts[id]);
            }
            _timeouts = {};
            for (var key in _envelopes) {
                var envelope = _envelopes[key][0];
                var metaConnect = _envelopes[key][1];
                if (metaConnect) {
                    _connected = false;
                }
                envelope.onFailure(webSocket, envelope.messages, {
                    websocketCode: event.code,
                    reason: event.reason
                });
            }
            _envelopes = {};
            _webSocket = null;
        };
        _self.registered = function(type, cometd) {
            _super.registered(type, cometd);
            _cometd = cometd;
        };
        _self.accept = function(version, crossDomain, url) {
            return _webSocketSupported && !!org.cometd.WebSocket && _cometd.websocketEnabled !== false;
        };
        _self.send = function(envelope, metaConnect) {
            this._debug('Transport', this.getType(), 'sending', envelope, 'metaConnect =', metaConnect);
            var messageIds = [];
            for (var i = 0; i < envelope.messages.length; ++i) {
                var message = envelope.messages[i];
                if (message.id) {
                    messageIds.push(message.id);
                }
            }
            _envelopes[messageIds.join(',')] = [envelope, metaConnect];
            this._debug('Transport', this.getType(), 'stored envelope, envelopes', _envelopes);
            _send.call(this, _webSocket, envelope, metaConnect);
        };
        _self.webSocketClose = function(webSocket, code, reason) {
            try {
                webSocket.close(code, reason);
            } catch (x) {
                this._debug(x);
            }
        };
        _self.abort = function() {
            _super.abort();
            if (_webSocket) {
                var event = {
                    code: 1001,
                    reason: 'Abort'
                };
                this.webSocketClose(_webSocket, event.code, event.reason);
                this.onClose(_webSocket, event);
            }
            this.reset();
        };
        return _self;
    };
    org.cometd.Cometd = function(name) {
        var _cometd = this;
        var _name = name || 'default';
        var _crossDomain = false;
        var _transports = new org.cometd.TransportRegistry();
        var _transport;
        var _status = 'disconnected';
        var _messageId = 0;
        var _clientId = null;
        var _batch = 0;
        var _messageQueue = [];
        var _internalBatch = false;
        var _listeners = {};
        var _backoff = 0;
        var _scheduledSend = null;
        var _extensions = [];
        var _advice = {};
        var _handshakeProps;
        var _handshakeCallback;
        var _callbacks = {};
        var _reestablish = false;
        var _connected = false;
        var _config = {
            protocol: null,
            stickyReconnect: true,
            connectTimeout: 0,
            maxConnections: 2,
            backoffIncrement: 1000,
            maxBackoff: 60000,
            logLevel: 'info',
            reverseIncomingExtensions: true,
            maxNetworkDelay: 10000,
            requestHeaders: {},
            appendMessageTypeToURL: true,
            autoBatch: false,
            advice: {
                timeout: 60000,
                interval: 0,
                reconnect: 'retry'
            }
        };
    
        function _fieldValue(object, name) {
            try {
                return object[name];
            } catch (x) {
                return undefined;
            }
        }
        this._mixin = function(deep, target, objects) {
            var result = target || {};
            for (var i = 2; i < arguments.length; ++i) {
                var object = arguments[i];
                if (object === undefined || object === null) {
                    continue;
                }
                for (var propName in object) {
                    var prop = _fieldValue(object, propName);
                    var targ = _fieldValue(result, propName);
                    if (prop === target) {
                        continue;
                    }
                    if (prop === undefined) {
                        continue;
                    }
                    if (deep && typeof prop === 'object' && prop !== null) {
                        if (prop instanceof Array) {
                            result[propName] = this._mixin(deep, targ instanceof Array ? targ : [], prop);
                        } else {
                            var source = typeof targ === 'object' && !(targ instanceof Array) ? targ : {};
                            result[propName] = this._mixin(deep, source, prop);
                        }
                    } else {
                        result[propName] = prop;
                    }
                }
            }
            return result;
        };
    
        function _isString(value) {
            return org.cometd.Utils.isString(value);
        }
    
        function _isFunction(value) {
            if (value === undefined || value === null) {
                return false;
            }
            return typeof value === 'function';
        }
    
        function _log(level, args) {
            if (window.console) {
                var logger = window.console[level];
                if (_isFunction(logger)) {
                    logger.apply(window.console, args);
                }
            }
        }
        this._warn = function() {
            _log('warn', arguments);
        };
        this._info = function() {
            if (_config.logLevel !== 'warn') {
                _log('info', arguments);
            }
        };
        this._debug = function() {
            if (_config.logLevel === 'debug') {
                _log('debug', arguments);
            }
        };
        this._isCrossDomain = function(hostAndPort) {
            return hostAndPort && hostAndPort !== window.location.host;
        };
    
        function _configure(configuration) {
            _cometd._debug('Configuring cometd object with', configuration);
            if (_isString(configuration)) {
                configuration = {
                    url: configuration
                };
            }
            if (!configuration) {
                configuration = {};
            }
            _config = _cometd._mixin(false, _config, configuration);
            var url = _cometd.getURL();
            if (!url) {
                throw 'Missing required configuration parameter \'url\' specifying the Bayeux server URL';
            }
            var urlParts = /(^https?:\/\/)?(((\[[^\]]+\])|([^:\/\?#]+))(:(\d+))?)?([^\?#]*)(.*)?/.exec(url);
            var hostAndPort = urlParts[2];
            var uri = urlParts[8];
            var afterURI = urlParts[9];
            _crossDomain = _cometd._isCrossDomain(hostAndPort);
            if (_config.appendMessageTypeToURL) {
                if (afterURI !== undefined && afterURI.length > 0) {
                    _cometd._info('Appending message type to URI ' + uri + afterURI + ' is not supported, disabling \'appendMessageTypeToURL\' configuration');
                    _config.appendMessageTypeToURL = false;
                } else {
                    var uriSegments = uri.split('/');
                    var lastSegmentIndex = uriSegments.length - 1;
                    if (uri.match(/\/$/)) {
                        lastSegmentIndex -= 1;
                    }
                    if (uriSegments[lastSegmentIndex].indexOf('.') >= 0) {
                        _cometd._info('Appending message type to URI ' + uri + ' is not supported, disabling \'appendMessageTypeToURL\' configuration');
                        _config.appendMessageTypeToURL = false;
                    }
                }
            }
        }
    
        function _removeListener(subscription) {
            if (subscription) {
                var subscriptions = _listeners[subscription.channel];
                if (subscriptions && subscriptions[subscription.id]) {
                    delete subscriptions[subscription.id];
                    _cometd._debug('Removed', subscription.listener ? 'listener' : 'subscription', subscription);
                }
            }
        }
    
        function _removeSubscription(subscription) {
            if (subscription && !subscription.listener) {
                _removeListener(subscription);
            }
        }
    
        function _clearSubscriptions() {
            for (var channel in _listeners) {
                var subscriptions = _listeners[channel];
                if (subscriptions) {
                    for (var i = 0; i < subscriptions.length; ++i) {
                        _removeSubscription(subscriptions[i]);
                    }
                }
            }
        }
    
        function _setStatus(newStatus) {
            if (_status !== newStatus) {
                _cometd._debug('Status', _status, '->', newStatus);
                _status = newStatus;
            }
        }
    
        function _isDisconnected() {
            return _status === 'disconnecting' || _status === 'disconnected';
        }
    
        function _nextMessageId() {
            return ++_messageId;
        }
    
        function _applyExtension(scope, callback, name, message, outgoing) {
            try {
                return callback.call(scope, message);
            } catch (x) {
                _cometd._debug('Exception during execution of extension', name, x);
                var exceptionCallback = _cometd.onExtensionException;
                if (_isFunction(exceptionCallback)) {
                    _cometd._debug('Invoking extension exception callback', name, x);
                    try {
                        exceptionCallback.call(_cometd, x, name, outgoing, message);
                    } catch (xx) {
                        _cometd._info('Exception during execution of exception callback in extension', name, xx);
                    }
                }
                return message;
            }
        }
    
        function _applyIncomingExtensions(message) {
            for (var i = 0; i < _extensions.length; ++i) {
                if (message === undefined || message === null) {
                    break;
                }
                var index = _config.reverseIncomingExtensions ? _extensions.length - 1 - i : i;
                var extension = _extensions[index];
                var callback = extension.extension.incoming;
                if (_isFunction(callback)) {
                    var result = _applyExtension(extension.extension, callback, extension.name, message, false);
                    message = result === undefined ? message : result;
                }
            }
            return message;
        }
    
        function _applyOutgoingExtensions(message) {
            for (var i = 0; i < _extensions.length; ++i) {
                if (message === undefined || message === null) {
                    break;
                }
                var extension = _extensions[i];
                var callback = extension.extension.outgoing;
                if (_isFunction(callback)) {
                    var result = _applyExtension(extension.extension, callback, extension.name, message, true);
                    message = result === undefined ? message : result;
                }
            }
            return message;
        }
    
        function _notify(channel, message) {
            var subscriptions = _listeners[channel];
            if (subscriptions && subscriptions.length > 0) {
                for (var i = 0; i < subscriptions.length; ++i) {
                    var subscription = subscriptions[i];
                    if (subscription) {
                        try {
                            subscription.callback.call(subscription.scope, message);
                        } catch (x) {
                            _cometd._debug('Exception during notification', subscription, message, x);
                            var listenerCallback = _cometd.onListenerException;
                            if (_isFunction(listenerCallback)) {
                                _cometd._debug('Invoking listener exception callback', subscription, x);
                                try {
                                    listenerCallback.call(_cometd, x, subscription, subscription.listener, message);
                                } catch (xx) {
                                    _cometd._info('Exception during execution of listener callback', subscription, xx);
                                }
                            }
                        }
                    }
                }
            }
        }
    
        function _notifyListeners(channel, message) {
            _notify(channel, message);
            var channelParts = channel.split('/');
            var last = channelParts.length - 1;
            for (var i = last; i > 0; --i) {
                var channelPart = channelParts.slice(0, i).join('/') + '/*';
                if (i === last) {
                    _notify(channelPart, message);
                }
                channelPart += '*';
                _notify(channelPart, message);
            }
        }
    
        function _cancelDelayedSend() {
            if (_scheduledSend !== null) {
                org.cometd.Utils.clearTimeout(_scheduledSend);
            }
            _scheduledSend = null;
        }
    
        function _delayedSend(operation) {
            _cancelDelayedSend();
            var delay = _advice.interval + _backoff;
            _cometd._debug('Function scheduled in', delay, 'ms, interval =', _advice.interval, 'backoff =', _backoff, operation);
            _scheduledSend = org.cometd.Utils.setTimeout(_cometd, operation, delay);
        }
        var _handleMessages;
        var _handleFailure;
    
        function _send(sync, messages, longpoll, extraPath) {
            for (var i = 0; i < messages.length; ++i) {
                var message = messages[i];
                var messageId = '' + _nextMessageId();
                message.id = messageId;
                if (_clientId) {
                    message.clientId = _clientId;
                }
                var callback = undefined;
                if (_isFunction(message._callback)) {
                    callback = message._callback;
                    delete message._callback;
                }
                message = _applyOutgoingExtensions(message);
                if (message !== undefined && message !== null) {
                    message.id = messageId;
                    messages[i] = message;
                    if (callback) {
                        _callbacks[messageId] = callback;
                    }
                } else {
                    messages.splice(i--, 1);
                }
            }
            if (messages.length === 0) {
                return;
            }
            var url = _cometd.getURL();
            if (_config.appendMessageTypeToURL) {
                if (!url.match(/\/$/)) {
                    url = url + '/';
                }
                if (extraPath) {
                    url = url + extraPath;
                }
            }
            var envelope = {
                url: url,
                sync: sync,
                messages: messages,
                onSuccess: function(rcvdMessages) {
                    try {
                        _handleMessages.call(_cometd, rcvdMessages);
                    } catch (x) {
                        _cometd._debug('Exception during handling of messages', x);
                    }
                },
                onFailure: function(conduit, messages, failure) {
                    try {
                        failure.connectionType = _cometd.getTransport().getType();
                        _handleFailure.call(_cometd, conduit, messages, failure);
                    } catch (x) {
                        _cometd._debug('Exception during handling of failure', x);
                    }
                }
            };
            _cometd._debug('Send', envelope);
            _transport.send(envelope, longpoll);
        }
    
        function _queueSend(message) {
            if (_batch > 0 || _internalBatch === true) {
                _messageQueue.push(message);
            } else {
                _send(false, [message], false);
            }
        }
        this.send = _queueSend;
    
        function _resetBackoff() {
            _backoff = 0;
        }
    
        function _increaseBackoff() {
            if (_backoff < _config.maxBackoff) {
                _backoff += _config.backoffIncrement;
            }
        }
    
        function _startBatch() {
            ++_batch;
        }
    
        function _flushBatch() {
            var messages = _messageQueue;
            _messageQueue = [];
            if (messages.length > 0) {
                _send(false, messages, false);
            }
        }
    
        function _endBatch() {
            --_batch;
            if (_batch < 0) {
                throw 'Calls to startBatch() and endBatch() are not paired';
            }
            if (_batch === 0 && !_isDisconnected() && !_internalBatch) {
                _flushBatch();
            }
        }
    
        function _connect() {
            if (!_isDisconnected()) {
                var message = {
                    channel: '/meta/connect',
                    connectionType: _transport.getType()
                };
                if (!_connected) {
                    message.advice = {
                        timeout: 0
                    };
                }
                _setStatus('connecting');
                _cometd._debug('Connect sent', message);
                _send(false, [message], true, 'connect');
                _setStatus('connected');
            }
        }
    
        function _delayedConnect() {
            _setStatus('connecting');
            _delayedSend(function() {
                _connect();
            });
        }
    
        function _updateAdvice(newAdvice) {
            if (newAdvice) {
                _advice = _cometd._mixin(false, {}, _config.advice, newAdvice);
                _cometd._debug('New advice', _advice);
            }
        }
    
        function _disconnect(abort) {
            _cancelDelayedSend();
            if (abort) {
                _transport.abort();
            }
            _clientId = null;
            _setStatus('disconnected');
            _batch = 0;
            _resetBackoff();
            _transport = null;
            if (_messageQueue.length > 0) {
                _handleFailure.call(_cometd, undefined, _messageQueue, {
                    reason: 'Disconnected'
                });
                _messageQueue = [];
            }
        }
    
        function _notifyTransportFailure(oldTransport, newTransport, failure) {
            var callback = _cometd.onTransportFailure;
            if (_isFunction(callback)) {
                _cometd._debug('Invoking transport failure callback', oldTransport, newTransport, failure);
                try {
                    callback.call(_cometd, oldTransport, newTransport, failure);
                } catch (x) {
                    _cometd._info('Exception during execution of transport failure callback', x);
                }
            }
        }
    
        function _handshake(handshakeProps, handshakeCallback) {
            if (_isFunction(handshakeProps)) {
                handshakeCallback = handshakeProps;
                handshakeProps = undefined;
            }
            _clientId = null;
            _clearSubscriptions();
            if (_isDisconnected()) {
                _transports.reset();
                _updateAdvice(_config.advice);
            } else {
                _updateAdvice(_cometd._mixin(false, _advice, {
                    reconnect: 'retry'
                }));
            }
            _batch = 0;
            _internalBatch = true;
            _handshakeProps = handshakeProps;
            _handshakeCallback = handshakeCallback;
            var version = '1.0';
            var url = _cometd.getURL();
            var transportTypes = _transports.findTransportTypes(version, _crossDomain, url);
            var bayeuxMessage = {
                version: version,
                minimumVersion: version,
                channel: '/meta/handshake',
                supportedConnectionTypes: transportTypes,
                _callback: handshakeCallback,
                advice: {
                    timeout: _advice.timeout,
                    interval: _advice.interval
                }
            };
            var message = _cometd._mixin(false, {}, _handshakeProps, bayeuxMessage);
            if (!_transport) {
                _transport = _transports.negotiateTransport(transportTypes, version, _crossDomain, url);
                if (!_transport) {
                    var failure = 'Could not find initial transport among: ' + _transports.getTransportTypes();
                    _cometd._warn(failure);
                    throw failure;
                }
            }
            _cometd._debug('Initial transport is', _transport.getType());
            _setStatus('handshaking');
            _cometd._debug('Handshake sent', message);
            _send(false, [message], false, 'handshake');
        }
    
        function _delayedHandshake() {
            _setStatus('handshaking');
            _internalBatch = true;
            _delayedSend(function() {
                _handshake(_handshakeProps, _handshakeCallback);
            });
        }
    
        function _handleCallback(message) {
            var callback = _callbacks[message.id];
            if (_isFunction(callback)) {
                delete _callbacks[message.id];
                callback.call(_cometd, message);
            }
        }
    
        function _failHandshake(message) {
            _handleCallback(message);
            _notifyListeners('/meta/handshake', message);
            _notifyListeners('/meta/unsuccessful', message);
            var retry = !_isDisconnected() && _advice.reconnect !== 'none';
            if (retry) {
                _increaseBackoff();
                _delayedHandshake();
            } else {
                _disconnect(false);
            }
        }
    
        function _handshakeResponse(message) {
            if (message.successful) {
                _clientId = message.clientId;
                var url = _cometd.getURL();
                var newTransport = _transports.negotiateTransport(message.supportedConnectionTypes, message.version, _crossDomain, url);
                if (newTransport === null) {
                    var failure = 'Could not negotiate transport with server; client=[' +
                        _transports.findTransportTypes(message.version, _crossDomain, url) +
                        '], server=[' + message.supportedConnectionTypes + ']';
                    var oldTransport = _cometd.getTransport();
                    _notifyTransportFailure(oldTransport.getType(), null, {
                        reason: failure,
                        connectionType: oldTransport.getType(),
                        transport: oldTransport
                    });
                    _cometd._warn(failure);
                    _transport.reset();
                    _failHandshake(message);
                    return;
                } else if (_transport !== newTransport) {
                    _cometd._debug('Transport', _transport.getType(), '->', newTransport.getType());
                    _transport = newTransport;
                }
                _internalBatch = false;
                _flushBatch();
                message.reestablish = _reestablish;
                _reestablish = true;
                _handleCallback(message);
                _notifyListeners('/meta/handshake', message);
                var action = _isDisconnected() ? 'none' : _advice.reconnect;
                switch (action) {
                    case 'retry':
                        _resetBackoff();
                        _delayedConnect();
                        break;
                    case 'none':
                        _disconnect(false);
                        break;
                    default:
                        throw 'Unrecognized advice action ' + action;
                }
            } else {
                _failHandshake(message);
            }
        }
    
        function _handshakeFailure(message) {
            var version = '1.0';
            var url = _cometd.getURL();
            var oldTransport = _cometd.getTransport();
            var transportTypes = _transports.findTransportTypes(version, _crossDomain, url);
            var newTransport = _transports.negotiateTransport(transportTypes, version, _crossDomain, url);
            if (!newTransport) {
                _notifyTransportFailure(oldTransport.getType(), null, message.failure);
                _cometd._warn('Could not negotiate transport; client=[' + transportTypes + ']');
                _transport.reset();
                _failHandshake(message);
            } else {
                _cometd._debug('Transport', oldTransport.getType(), '->', newTransport.getType());
                _notifyTransportFailure(oldTransport.getType(), newTransport.getType(), message.failure);
                _failHandshake(message);
                _transport = newTransport;
            }
        }
    
        function _failConnect(message) {
            _notifyListeners('/meta/connect', message);
            _notifyListeners('/meta/unsuccessful', message);
            var action = _isDisconnected() ? 'none' : _advice.reconnect;
            switch (action) {
                case 'retry':
                    _delayedConnect();
                    _increaseBackoff();
                    break;
                case 'handshake':
                    _transports.reset();
                    _resetBackoff();
                    _delayedHandshake();
                    break;
                case 'none':
                    _disconnect(false);
                    break;
                default:
                    throw 'Unrecognized advice action' + action;
            }
        }
    
        function _connectResponse(message) {
            _connected = message.successful;
            if (_connected) {
                _notifyListeners('/meta/connect', message);
                var action = _isDisconnected() ? 'none' : _advice.reconnect;
                switch (action) {
                    case 'retry':
                        _resetBackoff();
                        _delayedConnect();
                        break;
                    case 'none':
                        _disconnect(false);
                        break;
                    default:
                        throw 'Unrecognized advice action ' + action;
                }
            } else {
                _failConnect(message);
            }
        }
    
        function _connectFailure(message) {
            _connected = false;
            _failConnect(message);
        }
    
        function _failDisconnect(message) {
            _disconnect(true);
            _handleCallback(message);
            _notifyListeners('/meta/disconnect', message);
            _notifyListeners('/meta/unsuccessful', message);
        }
    
        function _disconnectResponse(message) {
            if (message.successful) {
                _disconnect(false);
                _handleCallback(message);
                _notifyListeners('/meta/disconnect', message);
            } else {
                _failDisconnect(message);
            }
        }
    
        function _disconnectFailure(message) {
            _failDisconnect(message);
        }
    
        function _failSubscribe(message) {
            var subscriptions = _listeners[message.subscription];
            if (subscriptions) {
                for (var i = subscriptions.length - 1; i >= 0; --i) {
                    var subscription = subscriptions[i];
                    if (subscription && !subscription.listener) {
                        delete subscriptions[i];
                        _cometd._debug('Removed failed subscription', subscription);
                        break;
                    }
                }
            }
            _handleCallback(message);
            _notifyListeners('/meta/subscribe', message);
            _notifyListeners('/meta/unsuccessful', message);
        }
    
        function _subscribeResponse(message) {
            if (message.successful) {
                _handleCallback(message);
                _notifyListeners('/meta/subscribe', message);
            } else {
                _failSubscribe(message);
            }
        }
    
        function _subscribeFailure(message) {
            _failSubscribe(message);
        }
    
        function _failUnsubscribe(message) {
            _handleCallback(message);
            _notifyListeners('/meta/unsubscribe', message);
            _notifyListeners('/meta/unsuccessful', message);
        }
    
        function _unsubscribeResponse(message) {
            if (message.successful) {
                _handleCallback(message);
                _notifyListeners('/meta/unsubscribe', message);
            } else {
                _failUnsubscribe(message);
            }
        }
    
        function _unsubscribeFailure(message) {
            _failUnsubscribe(message);
        }
    
        function _failMessage(message) {
            _handleCallback(message);
            _notifyListeners('/meta/publish', message);
            _notifyListeners('/meta/unsuccessful', message);
        }
    
        function _messageResponse(message) {
            if (message.successful === undefined) {
                if (message.data !== undefined) {
                    _notifyListeners(message.channel, message);
                } else {
                    _cometd._warn('Unknown Bayeux Message', message);
                }
            } else {
                if (message.successful) {
                    _handleCallback(message);
                    _notifyListeners('/meta/publish', message);
                } else {
                    _failMessage(message);
                }
            }
        }
    
        function _messageFailure(failure) {
            _failMessage(failure);
        }
    
        function _receive(message) {
            message = _applyIncomingExtensions(message);
            if (message === undefined || message === null) {
                return;
            }
            _updateAdvice(message.advice);
            var channel = message.channel;
            switch (channel) {
                case '/meta/handshake':
                    _handshakeResponse(message);
                    break;
                case '/meta/connect':
                    _connectResponse(message);
                    break;
                case '/meta/disconnect':
                    _disconnectResponse(message);
                    break;
                case '/meta/subscribe':
                    _subscribeResponse(message);
                    break;
                case '/meta/unsubscribe':
                    _unsubscribeResponse(message);
                    break;
                default:
                    _messageResponse(message);
                    break;
            }
        }
        this.receive = _receive;
        _handleMessages = function(rcvdMessages) {
            _cometd._debug('Received', rcvdMessages);
            for (var i = 0; i < rcvdMessages.length; ++i) {
                var message = rcvdMessages[i];
                _receive(message);
            }
        };
        _handleFailure = function(conduit, messages, failure) {
            _cometd._debug('handleFailure', conduit, messages, failure);
            failure.transport = conduit;
            for (var i = 0; i < messages.length; ++i) {
                var message = messages[i];
                var failureMessage = {
                    id: message.id,
                    successful: false,
                    channel: message.channel,
                    failure: failure
                };
                failure.message = message;
                switch (message.channel) {
                    case '/meta/handshake':
                        _handshakeFailure(failureMessage);
                        break;
                    case '/meta/connect':
                        _connectFailure(failureMessage);
                        break;
                    case '/meta/disconnect':
                        _disconnectFailure(failureMessage);
                        break;
                    case '/meta/subscribe':
                        failureMessage.subscription = message.subscription;
                        _subscribeFailure(failureMessage);
                        break;
                    case '/meta/unsubscribe':
                        failureMessage.subscription = message.subscription;
                        _unsubscribeFailure(failureMessage);
                        break;
                    default:
                        _messageFailure(failureMessage);
                        break;
                }
            }
        };
    
        function _hasSubscriptions(channel) {
            var subscriptions = _listeners[channel];
            if (subscriptions) {
                for (var i = 0; i < subscriptions.length; ++i) {
                    if (subscriptions[i]) {
                        return true;
                    }
                }
            }
            return false;
        }
    
        function _resolveScopedCallback(scope, callback) {
            var delegate = {
                scope: scope,
                method: callback
            };
            if (_isFunction(scope)) {
                delegate.scope = undefined;
                delegate.method = scope;
            } else {
                if (_isString(callback)) {
                    if (!scope) {
                        throw 'Invalid scope ' + scope;
                    }
                    delegate.method = scope[callback];
                    if (!_isFunction(delegate.method)) {
                        throw 'Invalid callback ' + callback + ' for scope ' + scope;
                    }
                } else if (!_isFunction(callback)) {
                    throw 'Invalid callback ' + callback;
                }
            }
            return delegate;
        }
    
        function _addListener(channel, scope, callback, isListener) {
            var delegate = _resolveScopedCallback(scope, callback);
            _cometd._debug('Adding', isListener ? 'listener' : 'subscription', 'on', channel, 'with scope', delegate.scope, 'and callback', delegate.method);
            var subscription = {
                channel: channel,
                scope: delegate.scope,
                callback: delegate.method,
                listener: isListener
            };
            var subscriptions = _listeners[channel];
            if (!subscriptions) {
                subscriptions = [];
                _listeners[channel] = subscriptions;
            }
            subscription.id = subscriptions.push(subscription) - 1;
            _cometd._debug('Added', isListener ? 'listener' : 'subscription', subscription);
            subscription[0] = channel;
            subscription[1] = subscription.id;
            return subscription;
        }
        this.registerTransport = function(type, transport, index) {
            var result = _transports.add(type, transport, index);
            if (result) {
                this._debug('Registered transport', type);
                if (_isFunction(transport.registered)) {
                    transport.registered(type, this);
                }
            }
            return result;
        };
        this.getTransportTypes = function() {
            return _transports.getTransportTypes();
        };
        this.unregisterTransport = function(type) {
            var transport = _transports.remove(type);
            if (transport !== null) {
                this._debug('Unregistered transport', type);
                if (_isFunction(transport.unregistered)) {
                    transport.unregistered();
                }
            }
            return transport;
        };
        this.unregisterTransports = function() {
            _transports.clear();
        };
        this.findTransport = function(name) {
            return _transports.find(name);
        };
        this.configure = function(configuration) {
            _configure.call(this, configuration);
        };
        this.init = function(configuration, handshakeProps) {
            this.configure(configuration);
            this.handshake(handshakeProps);
        };
        this.handshake = function(handshakeProps, handshakeCallback) {
            _setStatus('disconnected');
            _reestablish = false;
            _handshake(handshakeProps, handshakeCallback);
        };
        this.disconnect = function(sync, disconnectProps, disconnectCallback) {
            if (_isDisconnected()) {
                return;
            }
            if (typeof sync !== 'boolean') {
                disconnectCallback = disconnectProps;
                disconnectProps = sync;
                sync = false;
            }
            if (_isFunction(disconnectProps)) {
                disconnectCallback = disconnectProps;
                disconnectProps = undefined;
            }
            var bayeuxMessage = {
                channel: '/meta/disconnect',
                _callback: disconnectCallback
            };
            var message = this._mixin(false, {}, disconnectProps, bayeuxMessage);
            _setStatus('disconnecting');
            _send(sync === true, [message], false, 'disconnect');
        };
        this.startBatch = function() {
            _startBatch();
        };
        this.endBatch = function() {
            _endBatch();
        };
        this.batch = function(scope, callback) {
            var delegate = _resolveScopedCallback(scope, callback);
            this.startBatch();
            try {
                delegate.method.call(delegate.scope);
                this.endBatch();
            } catch (x) {
                this._info('Exception during execution of batch', x);
                this.endBatch();
                throw x;
            }
        };
        this.addListener = function(channel, scope, callback) {
            if (arguments.length < 2) {
                throw 'Illegal arguments number: required 2, got ' + arguments.length;
            }
            if (!_isString(channel)) {
                throw 'Illegal argument type: channel must be a string';
            }
            return _addListener(channel, scope, callback, true);
        };
        this.removeListener = function(subscription) {
            if (!subscription || !subscription.channel || !("id" in subscription)) {
                throw 'Invalid argument: expected subscription, not ' + subscription;
            }
            _removeListener(subscription);
        };
        this.clearListeners = function() {
            _listeners = {};
        };
        this.subscribe = function(channel, scope, callback, subscribeProps, subscribeCallback) {
            if (arguments.length < 2) {
                throw 'Illegal arguments number: required 2, got ' + arguments.length;
            }
            if (!_isString(channel)) {
                throw 'Illegal argument type: channel must be a string';
            }
            if (_isDisconnected()) {
                throw 'Illegal state: already disconnected';
            }
            if (_isFunction(scope)) {
                subscribeCallback = subscribeProps;
                subscribeProps = callback;
                callback = scope;
                scope = undefined;
            }
            if (_isFunction(subscribeProps)) {
                subscribeCallback = subscribeProps;
                subscribeProps = undefined;
            }
            var send = !_hasSubscriptions(channel);
            var subscription = _addListener(channel, scope, callback, false);
            if (send) {
                var bayeuxMessage = {
                    channel: '/meta/subscribe',
                    subscription: channel,
                    _callback: subscribeCallback
                };
                var message = this._mixin(false, {}, subscribeProps, bayeuxMessage);
                _queueSend(message);
            }
            return subscription;
        };
        this.unsubscribe = function(subscription, unsubscribeProps, unsubscribeCallback) {
            if (arguments.length < 1) {
                throw 'Illegal arguments number: required 1, got ' + arguments.length;
            }
            if (_isDisconnected()) {
                throw 'Illegal state: already disconnected';
            }
            if (_isFunction(unsubscribeProps)) {
                unsubscribeCallback = unsubscribeProps;
                unsubscribeProps = undefined;
            }
            this.removeListener(subscription);
            var channel = subscription.channel;
            if (!_hasSubscriptions(channel)) {
                var bayeuxMessage = {
                    channel: '/meta/unsubscribe',
                    subscription: channel,
                    _callback: unsubscribeCallback
                };
                var message = this._mixin(false, {}, unsubscribeProps, bayeuxMessage);
                _queueSend(message);
            }
        };
        this.resubscribe = function(subscription, subscribeProps) {
            _removeSubscription(subscription);
            if (subscription) {
                return this.subscribe(subscription.channel, subscription.scope, subscription.callback, subscribeProps);
            }
            return undefined;
        };
        this.clearSubscriptions = function() {
            _clearSubscriptions();
        };
        this.publish = function(channel, content, publishProps, publishCallback) {
            if (arguments.length < 1) {
                throw 'Illegal arguments number: required 1, got ' + arguments.length;
            }
            if (!_isString(channel)) {
                throw 'Illegal argument type: channel must be a string';
            }
            if (/^\/meta\//.test(channel)) {
                throw 'Illegal argument: cannot publish to meta channels';
            }
            if (_isDisconnected()) {
                throw 'Illegal state: already disconnected';
            }
            if (_isFunction(content)) {
                publishCallback = content;
                content = publishProps = {};
            } else if (_isFunction(publishProps)) {
                publishCallback = publishProps;
                publishProps = {};
            }
            var bayeuxMessage = {
                channel: channel,
                data: content,
                _callback: publishCallback
            };
            var message = this._mixin(false, {}, publishProps, bayeuxMessage);
            _queueSend(message);
        };
        this.getStatus = function() {
            return _status;
        };
        this.isDisconnected = _isDisconnected;
        this.setBackoffIncrement = function(period) {
            _config.backoffIncrement = period;
        };
        this.getBackoffIncrement = function() {
            return _config.backoffIncrement;
        };
        this.getBackoffPeriod = function() {
            return _backoff;
        };
        this.setLogLevel = function(level) {
            _config.logLevel = level;
        };
        this.registerExtension = function(name, extension) {
            if (arguments.length < 2) {
                throw 'Illegal arguments number: required 2, got ' + arguments.length;
            }
            if (!_isString(name)) {
                throw 'Illegal argument type: extension name must be a string';
            }
            var existing = false;
            for (var i = 0; i < _extensions.length; ++i) {
                var existingExtension = _extensions[i];
                if (existingExtension.name === name) {
                    existing = true;
                    break;
                }
            }
            if (!existing) {
                _extensions.push({
                    name: name,
                    extension: extension
                });
                this._debug('Registered extension', name);
                if (_isFunction(extension.registered)) {
                    extension.registered(name, this);
                }
                return true;
            } else {
                this._info('Could not register extension with name', name, 'since another extension with the same name already exists');
                return false;
            }
        };
        this.unregisterExtension = function(name) {
            if (!_isString(name)) {
                throw 'Illegal argument type: extension name must be a string';
            }
            var unregistered = false;
            for (var i = 0; i < _extensions.length; ++i) {
                var extension = _extensions[i];
                if (extension.name === name) {
                    _extensions.splice(i, 1);
                    unregistered = true;
                    this._debug('Unregistered extension', name);
                    var ext = extension.extension;
                    if (_isFunction(ext.unregistered)) {
                        ext.unregistered();
                    }
                    break;
                }
            }
            return unregistered;
        };
        this.getExtension = function(name) {
            for (var i = 0; i < _extensions.length; ++i) {
                var extension = _extensions[i];
                if (extension.name === name) {
                    return extension.extension;
                }
            }
            return null;
        };
        this.getName = function() {
            return _name;
        };
        this.getClientId = function() {
            return _clientId;
        };
        this.getURL = function() {
            if (_transport && typeof _config.urls === 'object') {
                var url = _config.urls[_transport.getType()];
                if (url) {
                    return url;
                }
            }
            return _config.url;
        };
        this.getTransport = function() {
            return _transport;
        };
        this.getConfiguration = function() {
            return this._mixin(true, {}, _config);
        };
        this.getAdvice = function() {
            return this._mixin(true, {}, _advice);
        };
        org.cometd.WebSocket = window.WebSocket;
        if (!org.cometd.WebSocket) {
            org.cometd.WebSocket = window.MozWebSocket;
        }
    };
    if (typeof define === 'function' && define.amd) {
        define(function() {
            return org.cometd;
        });
    };
    /*! RESOURCE: /scripts/thirdparty/cometd/jquery/jquery.cometd.js */
    (function() {
        function bind($, org_cometd) {
            org_cometd.JSON.toJSON = (window.JSON && JSON.stringify) || (window.jaredJSON && window.jaredJSON.stringify);
            org_cometd.JSON.fromJSON = (window.JSON && JSON.parse) || (window.jaredJSON && window.jaredJSON.parse);
    
            function _setHeaders(xhr, headers) {
                if (headers) {
                    for (var headerName in headers) {
                        if (headerName.toLowerCase() === 'content-type') {
                            continue;
                        }
                        xhr.setRequestHeader(headerName, headers[headerName]);
                    }
                }
            }
    
            function LongPollingTransport() {
                var _super = new org_cometd.LongPollingTransport();
                var that = org_cometd.Transport.derive(_super);
                that.xhrSend = function(packet) {
                    return $.ajax({
                        url: packet.url,
                        async: packet.sync !== true,
                        type: 'POST',
                        contentType: 'application/json;charset=UTF-8',
                        data: packet.body,
                        xhrFields: {
                            withCredentials: true
                        },
                        beforeSend: function(xhr) {
                            _setHeaders(xhr, packet.headers);
                            return true;
                        },
                        success: packet.onSuccess,
                        error: function(xhr, reason, exception) {
                            packet.onError(reason, exception);
                        }
                    });
                };
                return that;
            }
    
            function CallbackPollingTransport() {
                var _super = new org_cometd.CallbackPollingTransport();
                var that = org_cometd.Transport.derive(_super);
                that.jsonpSend = function(packet) {
                    $.ajax({
                        url: packet.url,
                        async: packet.sync !== true,
                        type: 'GET',
                        dataType: 'jsonp',
                        jsonp: 'jsonp',
                        data: {
                            message: packet.body
                        },
                        beforeSend: function(xhr) {
                            _setHeaders(xhr, packet.headers);
                            return true;
                        },
                        success: packet.onSuccess,
                        error: function(xhr, reason, exception) {
                            packet.onError(reason, exception);
                        }
                    });
                };
                return that;
            }
            $.Cometd = function(name) {
                var cometd = new org_cometd.Cometd(name);
                if (org_cometd.WebSocket) {
                    cometd.registerTransport('websocket', new org_cometd.WebSocketTransport());
                }
                cometd.registerTransport('long-polling', new LongPollingTransport());
                cometd.registerTransport('callback-polling', new CallbackPollingTransport());
                return cometd;
            };
            $.cometd = new $.Cometd();
            return $.cometd;
        }
        if (typeof define === 'function' && define.amd) {
            define(['jquery', 'org/cometd'], bind);
        } else {
            bind(window.jQuery1110 || window.Zepto, org.cometd);
        }
    })();;
    /*! RESOURCE: /scripts/amb_properties.js */
    var amb = amb || {
        properties: {
            servletURI: 'amb/',
            logLevel: 'info',
            loginWindow: 'true'
        }
    };;
    /*! RESOURCE: /scripts/amb.Logger.js */
    amb['Logger'] = function(callerType) {
        var _debugEnabled = amb['properties']['logLevel'] == 'debug';
    
        function print(message) {
            console.log(callerType + ' ' + message);
        }
        return {
            debug: function(message) {
                if (_debugEnabled)
                    print('[DEBUG] ' + message);
            },
            addInfoMessage: function(message) {
                print('[INFO] ' + message);
            },
            addErrorMessage: function(message) {
                print('[ERROR] ' + message);
            }
        }
    };;
    /*! RESOURCE: /scripts/amb.EventManager.js */
    amb.EventManager = function EventManager(events) {
        var _subscriptions = [];
        var _idCounter = 0;
    
        function _getSubscriptions(event) {
            var subscriptions = [];
            for (var i = 0; i < _subscriptions.length; i++) {
                if (_subscriptions[i].event == event)
                    subscriptions.push(_subscriptions[i]);
            }
            return subscriptions;
        }
        return {
            subscribe: function(event, callback) {
                var id = _idCounter++;
                _subscriptions.push({
                    event: event,
                    callback: callback,
                    id: id
                });
                return id;
            },
            unsubscribe: function(id) {
                for (var i = 0; i < _subscriptions.length; i++)
                    if (id == _subscriptions[i].id)
                        _subscriptions.splice(i, 1);
            },
            publish: function(event, args) {
                var subscriptions = _getSubscriptions(event);
                for (var i = 0; i < subscriptions.length; i++)
                    subscriptions[i].callback.apply(null, args);
            },
            getEvents: function() {
                return events;
            }
        }
    };;
    /*! RESOURCE: /scripts/amb.ServerConnection.js */
    amb.ServerConnection = function ServerConnection(cometd) {
        var connected = false;
        var disconnecting = false;
        var eventManager = new amb.EventManager({
            CONNECTION_INITIALIZED: 'connection.initialized',
            CONNECTION_OPENED: 'connection.opened',
            CONNECTION_CLOSED: 'connection.closed',
            CONNECTION_BROKEN: 'connection.broken',
            SESSION_LOGGED_IN: 'session.logged.in',
            SESSION_LOGGED_OUT: 'session.logged.out'
        });
        var state = "closed";
        var LOGGER = new amb.Logger('amb.ServerConnection');
        _initializeMetaChannelListeners();
        var loggedIn = true;
        var loginWindow = null;
        var loginWindowEnabled = amb.properties['loginWindow'] === 'true';
        var lastError = null;
        var errorMessages = {
            'UNKNOWN_CLIENT': '402::Unknown client'
        };
        var loginWindowOverride = false;
        var ambServerConnection = {};
        ambServerConnection.connect = function() {
            if (connected) {
                console.log(">>> connection exists, request satisfied");
                return;
            }
            LOGGER.debug('Connecting to glide amb server -> ' + amb['properties']['servletURI']);
            LOGGER.debug('Connecting to glide amb server -> ' + amb['properties']['servletURI']);
            cometd.configure({
                url: _getRelativePath(amb['properties']['servletURI']),
                logLevel: amb['properties']['logLevel']
            });
            cometd.handshake();
        };
        ambServerConnection.reload = function() {
            cometd.reload();
        };
        ambServerConnection.abort = function() {
            cometd.getTransport().abort();
        };
        ambServerConnection.disconnect = function() {
            LOGGER.debug('Disconnecting from glide amb server..');
            disconnecting = true;
            cometd.disconnect();
        };
    
        function _initializeMetaChannelListeners() {
            cometd.addListener('/meta/handshake', this, _metaHandshake);
            cometd.addListener('/meta/connect', this, _metaConnect);
        }
    
        function _metaHandshake(message) {
            setTimeout(function() {
                if (message['successful'])
                    _connectionInitialized();
            }, 0);
        }
    
        function _metaConnect(message) {
            if (disconnecting) {
                setTimeout(function() {
                    connected = false;
                    _connectionClosed();
                }, 0);
                return;
            }
            var error = message['error'];
            if (error)
                lastError = error;
            _sessionStatus(message);
            var wasConnected = connected;
            connected = (message['successful'] === true);
            if (!wasConnected && connected)
                _connectionOpened();
            else if (wasConnected && !connected)
                _connectionBroken();
        }
    
        function _connectionInitialized() {
            LOGGER.debug('Connection initialized');
            state = "initialized";
            eventManager.publish(eventManager.getEvents().CONNECTION_INITIALIZED);
        }
    
        function _connectionOpened() {
            LOGGER.debug('Connection opened');
            state = "opened";
            eventManager.publish(eventManager.getEvents().CONNECTION_OPENED);
        }
    
        function _connectionClosed() {
            LOGGER.debug('Connection closed');
            state = "closed";
            eventManager.publish(eventManager.getEvents().CONNECTION_CLOSED);
        }
    
        function _connectionBroken() {
            LOGGER.addErrorMessage('Connection broken');
            state = "broken";
            eventManager.publish(eventManager.getEvents().CONNECTION_BROKEN);
        }
    
        function _sessionStatus(message) {
            var ext = message['ext'];
            if (ext) {
                var sessionStatus = ext['glide.session.status'];
                loginWindowOverride = ext['glide.amb.login.window.override'] === true;
                LOGGER.debug('session.status - ' + sessionStatus);
                switch (sessionStatus) {
                    case 'session.logged.out':
                        if (loggedIn)
                            _logout();
                        break;
                    case 'session.logged.in':
                        if (!loggedIn)
                            _login();
                        break;
                    default:
                        LOGGER.debug("unknown session status - " + sessionStatus);
                        break;
                }
            }
        }
    
        function _login() {
            loggedIn = true;
            LOGGER.debug("LOGGED_IN event fire!");
            eventManager.publish(eventManager.getEvents().SESSION_LOGGED_IN);
            ambServerConnection.loginHide();
        }
    
        function _logout() {
            loggedIn = false;
            LOGGER.debug("LOGGED_OUT event fire!");
            eventManager.publish(eventManager.getEvents().SESSION_LOGGED_OUT);
            ambServerConnection.loginShow();
        }
        var modalContent = '<iframe src="/amb_login.do" frameborder="0" height="400px" width="405px" scrolling="no"></iframe>';
        var modalTemplate = '<div id="amb_disconnect_modal" tabindex="-1" aria-hidden="true" class="modal" role="dialog">' +
            '  <div class="modal-dialog small-modal" style="width:450px">' +
            '     <div class="modal-content">' +
            '        <header class="modal-header">' +
            '           <h4 id="small_modal1_title" class="modal-title">Login</h4>' +
            '        </header>' +
            '        <div class="modal-body">' +
            '        </div>' +
            '     </div>' +
            '  </div>' +
            '</div>';
    
        function _loginShow() {
            if (!loginWindowEnabled || loginWindowOverride)
                return;
            var dialog = new GlideModal('amb_disconnect_modal');
            if (dialog['renderWithContent']) {
                dialog.template = modalTemplate;
                dialog.renderWithContent(modalContent);
            } else {
                dialog.setBody(modalContent);
                dialog.render();
            }
            loginWindow = dialog;
        }
    
        function _loginHide() {
            if (!loginWindow)
                return;
            loginWindow.destroy();
            loginWindow = null;
        }
    
        function loginComplete() {
            _login();
        }
    
        function _getRelativePath(uri) {
            var relativePath = "";
            for (var i = 0; i < window.location.pathname.match(/\//g).length - 1; i++) {
                relativePath = "../" + relativePath;
            }
            return relativePath + uri;
        }
        ambServerConnection.loginShow = function() {
            _loginShow();
        };
        ambServerConnection.loginHide = function() {
            _loginHide();
        };
        ambServerConnection.getEvents = function() {
            return eventManager.getEvents();
        };
        ambServerConnection.getConnectionState = function() {
            return state;
        };
        ambServerConnection.getLastError = function() {
            return lastError;
        };
        ambServerConnection.setLastError = function(error) {
            lastError = error;
        };
        ambServerConnection.getErrorMessages = function() {
            return errorMessages;
        };
        ambServerConnection.isLoggedIn = function() {
            return loggedIn;
        };
        ambServerConnection.loginShow = function() {
            _loginShow();
        };
        ambServerConnection.loginHide = function() {
            _loginHide();
        };
        ambServerConnection.loginComplete = function() {
            _login();
        };
        ambServerConnection.getEvents = function() {
            return eventManager.getEvents();
        };
        ambServerConnection.subscribeToEvent = function(event, callback) {
            if (eventManager.getEvents().CONNECTION_OPENED == event && connected)
                callback();
            return eventManager.subscribe(event, callback);
        };
        ambServerConnection.unsubscribeFromEvent = function(id) {
            eventManager.unsubscribe(id);
        };
        ambServerConnection.getConnectionState = function() {
            return state;
        };
        ambServerConnection.isLoggedIn = function() {
            return loggedIn;
        };
        ambServerConnection.loginShow = function() {
            _loginShow();
        };
        ambServerConnection.loginHide = function() {
            _loginHide();
        };
        ambServerConnection.loginComplete = function() {
            _login();
        };
        ambServerConnection.isLoginWindowEnabled = function() {
            return loginWindowEnabled;
        };
        ambServerConnection.isLoginWindowOverride = function() {
            return loginWindowOverride;
        }
        return ambServerConnection;
    };;
    /*! RESOURCE: /scripts/amb.ChannelRedirect.js */
    amb.ChannelRedirect = function ChannelRedirect(cometd, serverConnection,
        channelProvider) {
        var initialized = false;
        var _cometd = cometd;
        var eventManager = new amb.EventManager({
            CHANNEL_REDIRECT: 'channel.redirect'
        });
        var LOGGER = new amb.Logger('amb.ChannelRedirect');
    
        function _onAdvice(advice) {
            LOGGER.debug('_onAdvice:' + advice.data.clientId);
            var fromChannel = channelProvider(advice.data.fromChannel);
            var toChannel = channelProvider(advice.data.toChannel);
            eventManager.publish(eventManager.getEvents().CHANNEL_REDIRECT, [fromChannel, toChannel]);
            LOGGER.debug(
                'published channel switch event, fromChannel:' + fromChannel.getName() +
                ', toChannel:' + toChannel.getName());
        }
        return {
            subscribeToEvent: function(event, callback) {
                return eventManager.subscribe(event, callback);
            },
            unsubscribeToEvent: function(id) {
                eventManager.unsubscribe(id);
            },
            getEvents: function() {
                return eventManager.getEvents();
            },
            initialize: function() {
                if (!initialized) {
                    var channelName = '/sn/meta/channel_redirect/' + _cometd.getClientId();
                    var metaChannel = channelProvider(channelName);
                    metaChannel.newListener(serverConnection, null).subscribe(_onAdvice);
                    LOGGER.debug("ChannelRedirect initialized: " + channelName);
                    initialized = true;
                }
            }
        }
    };;
    /*! RESOURCE: /scripts/amb.ChannelListener.js */
    amb.ChannelListener = function ChannelListener(channel, serverConnection,
        channelRedirect) {
        var id;
        var subscriberCallback;
        var LOGGER = new amb.Logger('amb.ChannelListener');
        var channelRedirectId = null;
        var connectOpenedEventId;
        var currentChannel = channel;
        return {
            getCallback: function() {
                return subscriberCallback;
            },
            getID: function() {
                return id;
            },
            subscribe: function(callback) {
                subscriberCallback = callback;
                if (channelRedirect)
                    channelRedirectId = channelRedirect.subscribeToEvent(
                        channelRedirect.getEvents().CHANNEL_REDIRECT, this._switchToChannel.bind(this));
                connectOpenedEventId = serverConnection.subscribeToEvent(serverConnection.getEvents().CONNECTION_OPENED,
                    this._subscribeWhenReady.bind(this));
                LOGGER.debug("Subscribed from channel: " + currentChannel.getName());
                return this;
            },
            resubscribe: function() {
                return this.subscribe(subscriberCallback);
            },
            _switchToChannel: function(fromChannel, toChannel) {
                if (!fromChannel || !toChannel)
                    return;
                if (fromChannel.getName() != currentChannel.getName())
                    return;
                this.unsubscribe();
                currentChannel = toChannel;
                this.subscribe(subscriberCallback);
            },
            _subscribeWhenReady: function() {
                LOGGER.debug("Subscribing to '" + currentChannel.getName() + "'...");
                id = currentChannel.subscribe(this);
            },
            unsubscribe: function() {
                channelRedirect.unsubscribeToEvent(channelRedirectId);
                currentChannel.unsubscribe(this);
                serverConnection.unsubscribeFromEvent(connectOpenedEventId);
                LOGGER.debug("Unsubscribed from channel: " + currentChannel.getName());
                return this;
            },
            publish: function(message) {
                currentChannel.publish(message);
            },
            getName: function() {
                return currentChannel.getName();
            }
        }
    };;
    /*! RESOURCE: /scripts/amb.Channel.js */
    amb.Channel = function Channel(cometd, channelName, initialized) {
        var subscription = null;
        var listeners = [];
        var LOGGER = new amb.Logger('amb.Channel');
        var idCounter = 0;
        var _initialized = initialized;
    
        function _disconnected() {
            var status = cometd.getStatus();
            return status === 'disconnecting' || status === 'disconnected';
        }
        return {
            newListener: function(serverConnection,
                channelRedirect) {
                return new amb.ChannelListener(this, serverConnection, channelRedirect);
            },
            subscribe: function(listener) {
                if (!listener.getCallback()) {
                    LOGGER.addErrorMessage('Cannot subscribe to channel: ' + channelName +
                        ', callback not provided');
                    return;
                }
                if (!subscription && _initialized) {
                    subscription = cometd.subscribe(channelName, this._handleResponse.bind(this));
                    LOGGER.debug('Successfully subscribed to channel: ' + channelName);
                }
                for (var i = 0; i < listeners.length; i++) {
                    if (listeners[i] === listener) {
                        LOGGER.debug('Channel listener already in the list');
                        return listener.getID();
                    }
                }
                var id = idCounter++;
                listeners.push(listener);
                return id;
            },
            subscribeOnInitCompletion: function(redirect) {
                _initialized = true;
                subscription = null;
                for (var i = 0; i < listeners.length; i++) {
                    listeners[i].subscribe();
                    LOGGER.debug('Successfully subscribed to channel: ' + channelName);
                }
            },
            resubscribe: function() {
                subscription = null;
                for (var i = 0; i < listeners.length; i++)
                    listeners[i].resubscribe();
            },
            _handleResponse: function(message) {
                for (var i = 0; i < listeners.length; i++)
                    listeners[i].getCallback()(message);
            },
            unsubscribe: function(listener) {
                if (!listener) {
                    LOGGER.addErrorMessage('Cannot unsubscribe from channel: ' + channelName +
                        ', listener argument does not exist');
                    return;
                }
                for (var i = 0; i < listeners.length; i++) {
                    if (listeners[i].getID() == listener.getID())
                        listeners.splice(i, 1);
                }
                if (listeners.length < 1 && subscription && !_disconnected()) {
                    cometd.unsubscribe(subscription);
                    subscription = null;
                }
                LOGGER.debug('Successfully unsubscribed from channel: ' + channelName);
            },
            publish: function(message) {
                cometd.publish(channelName, message);
            },
            getName: function() {
                return channelName;
            }
        }
    };;
    /*! RESOURCE: /scripts/amb.MessageClient.js */
    (function($) {
        amb.MessageClient = function MessageClient() {
            var cometd = new $.Cometd();
            cometd.unregisterTransport('websocket');
            cometd.unregisterTransport('callback-polling');
            var serverConnection = new amb.ServerConnection(cometd);
            var channels = {};
            var LOGGER = new amb.Logger('amb.MessageClient');
            var channelRedirect = null;
            var connected = false;
            var initialized = false;
            var uninitializedChannels = [];
            serverConnection.subscribeToEvent(serverConnection.getEvents().CONNECTION_BROKEN, _connectionBroken);
            serverConnection.subscribeToEvent(serverConnection.getEvents().CONNECTION_OPENED, _connectionOpened);
            serverConnection.subscribeToEvent(serverConnection.getEvents().CONNECTION_INITIALIZED, _connectionInitialized);
            var _connectionBrokenEvent = false;
    
            function _connectionBroken() {
                LOGGER.debug("connection broken!");
                _connectionBrokenEvent = true;
            }
    
            function _connectionInitialized() {
                initialized = true;
                _initChannelRedirect();
                channelRedirect.initialize();
                LOGGER.debug("Connection initialized. Initializing " + uninitializedChannels.length + " channels.");
                for (var i = 0; i < uninitializedChannels.length; i++) {
                    uninitializedChannels[i].subscribeOnInitCompletion();
                }
                uninitializedChannels = [];
            }
    
            function _connectionOpened() {
                if (_connectionBrokenEvent) {
                    LOGGER.debug("connection opened!");
                    _connectionBrokenEvent = false;
                    var sc = serverConnection;
                    if (sc.getLastError() !== sc.getErrorMessages().UNKNOWN_CLIENT)
                        return;
                    sc.setLastError(null);
                    LOGGER.debug("channel resubscribe!");
                    $.ajax({
                        url: "/amb_session_setup.do",
                        method: "GET",
                        contentType: "application/json;charset=UTF-8",
                        data: "",
                        dataType: "HTML",
                        headers: {
                            'X-UserToken': window.g_ck
                        }
                    }).done(function() {
                        for (var name in channels) {
                            var channel = channels[name];
                            channel.resubscribe();
                        }
                    });
                }
            }
    
            function _initChannelRedirect() {
                if (channelRedirect)
                    return;
                channelRedirect = new amb.ChannelRedirect(cometd, serverConnection, _getChannel);
            }
    
            function _getChannel(channelName) {
                if (channelName in channels)
                    return channels[channelName];
                var channel = new amb.Channel(cometd, channelName, initialized);
                channels[channelName] = channel;
                if (!initialized)
                    uninitializedChannels.push(channel);
                return channel;
            }
            return {
                getServerConnection: function() {
                    return serverConnection;
                },
                isLoggedIn: function() {
                    return serverConnection.isLoggedIn();
                },
                loginComplete: function() {
                    serverConnection.loginComplete();
                },
                connect: function() {
                    if (connected) {
                        LOGGER.addInfoMessage(">>> connection exists, request satisfied");
                        return;
                    }
                    connected = true;
                    serverConnection.connect();
                },
                reload: function() {
                    connected = false;
                    serverConnection.reload();
                },
                abort: function() {
                    connected = false;
                    serverConnection.abort();
                },
                disconnect: function() {
                    connected = false;
                    serverConnection.disconnect();
                },
                getConnectionEvents: function() {
                    return serverConnection.getEvents();
                },
                subscribeToEvent: function(event, callback) {
                    return serverConnection.subscribeToEvent(event, callback);
                },
                unsubscribeFromEvent: function(id) {
                    serverConnection.unsubscribeFromEvent(id);
                },
                getConnectionState: function() {
                    return serverConnection.getConnectionState();
                },
                getClientId: function() {
                    return cometd.getClientId();
                },
                getChannel: function(channelName) {
                    _initChannelRedirect();
                    var channel = _getChannel(channelName);
                    return channel.newListener(serverConnection, channelRedirect);
                },
                registerExtension: function(extensionName, extension) {
                    cometd.registerExtension(extensionName, extension);
                },
                unregisterExtension: function(extensionName) {
                    cometd.unregisterExtension(extensionName);
                },
                batch: function(block) {
                    cometd.batch(block);
                }
            }
        };
    })(jQuery1110);;
    /*! RESOURCE: /scripts/amb.MessageClientBuilder.js */
    (function($) {
        amb.getClient = function() {
            return getClient();
        }
    
        function getClient() {
            var _window = window.self;
            try {
                if (!(window.MSInputMethodContext && document.documentMode)) {
                    while (_window != _window.parent) {
                        if (_window.g_ambClient)
                            break;
                        _window = _window.parent;
                    }
                }
                if (_window.g_ambClient)
                    return _window.g_ambClient;
            } catch (e) {
                console.log("AMB getClient() tried to access parent from an iFrame. Caught error: " + e);
            }
            var client = buildClient();
            setClient(client);
            return client;
        }
    
        function setClient(client) {
            var _window = window.self;
            _window.g_ambClient = client;
            $(_window).unload(function() {
                _window.g_ambClient.disconnect();
            });
            _window.g_ambClient.connect();
        }
    
        function buildClient() {
            return (function() {
                var ambClient = new amb.MessageClient();
                return {
                    getServerConnection: function() {
                        return ambClient.getServerConnection();
                    },
                    connect: function() {
                        ambClient.connect();
                    },
                    abort: function() {
                        ambClient.abort();
                    },
                    disconnect: function() {
                        ambClient.disconnect();
                    },
                    getConnectionState: function() {
                        return ambClient.getConnectionState();
                    },
                    getState: function() {
                        return ambClient.getConnectionState();
                    },
                    getClientId: function() {
                        return ambClient.getClientId();
                    },
                    getChannel: function(channelName) {
                        var channel = ambClient.getChannel(channelName);
                        var originalSubscribe = channel.subscribe;
                        var originalUnsubscribe = channel.unsubscribe;
                        channel.subscribe = function(listener) {
                            originalSubscribe.call(channel, listener);
                            $(window).unload(function(event) {
                                originalUnsubscribe.call(channel);
                            });
                            return channel;
                        };
                        return channel;
                    },
                    getChannel0: function(channelName) {
                        return ambClient.getChannel(channelName);
                    },
                    registerExtension: function(extensionName, extension) {
                        ambClient.registerExtension(extensionName, extension);
                    },
                    unregisterExtension: function(extensionName) {
                        ambClient.unregisterExtension(extensionName);
                    },
                    batch: function(block) {
                        ambClient.batch(block);
                    },
                    subscribeToEvent: function(event, callback) {
                        return ambClient.subscribeToEvent(event, callback);
                    },
                    unsubscribeFromEvent: function(id) {
                        ambClient.unsubscribeFromEvent(id);
                    },
                    isLoggedIn: function() {
                        return ambClient.isLoggedIn();
                    },
                    getConnectionEvents: function() {
                        return ambClient.getConnectionEvents();
                    },
                    getEvents: function() {
                        return ambClient.getConnectionEvents();
                    },
                    loginComplete: function() {
                        ambClient.loginComplete();
                    }
                };
            })();
        }
    })(jQuery1110);;
    /*! RESOURCE: /scripts/amb_initialize.js */
    if (typeof g_amb_on_login === 'undefined') {
        amb.getClient();
    };;
    /*! RESOURCE: /scripts/app.ng.amb/app.ng.amb.js */
    angular.module("ng.amb", ['sn.common.presence', 'sn.common.util'])
        .value("ambLogLevel", 'info')
        .value("ambServletURI", '/amb')
        .value("cometd", angular.element.cometd)
        .value("ambLoginWindow", 'true');;
    /*! RESOURCE: /scripts/app.ng.amb/service.AMB.js */
    angular.module("ng.amb").service("amb", function(AMBOverlay, $window, $q, $log, $rootScope, $timeout) {
        "use strict";
        var ambClient = null;
        var _window = $window.self;
        var loginWindow = null;
        var sameScope = false;
        if (_window.g_ambClient) {
            ambClient = _window.g_ambClient;
            sameScope = true;
        }
        if (!ambClient)
            ambClient = amb.getClient();
        if (sameScope) {
            var serverConnection = ambClient.getServerConnection();
            serverConnection.loginShow = function() {
                if (!serverConnection.isLoginWindowEnabled())
                    return;
                if (loginWindow && loginWindow.isVisible())
                    return;
                if (serverConnection.isLoginWindowOverride())
                    return;
                loginWindow = new AMBOverlay();
                loginWindow.render();
                loginWindow.show();
            };
            serverConnection.loginHide = function() {
                if (!loginWindow)
                    return;
                loginWindow.hide();
                loginWindow.destroy();
                loginWindow = null;
            }
        }
        var connected = $q.defer();
        var connectionInterrupted = false;
        var monitorAMB = false;
        $timeout(function() {
            monitorAMB = true;
        }, 5 * 1000);
    
        function ambInterrupted() {
            var state = ambClient.getState();
            return monitorAMB && state !== "opened" && state !== "initialized"
        }
        var interruptionTimeout;
        var extendedInterruption = false;
    
        function setInterrupted(eventName) {
            connectionInterrupted = true;
            $rootScope.$broadcast(eventName);
            if (!interruptionTimeout) {
                interruptionTimeout = $timeout(function() {
                    extendedInterruption = true;
                }, 30 * 1000)
            }
            connected = $q.defer();
        }
        var connectOpenedEventId = ambClient.subscribeToEvent("connection.opened", function() {
            $rootScope.$broadcast("amb.connection.opened");
            if (interruptionTimeout) {
                $timeout.cancel(interruptionTimeout);
                interruptionTimeout = null;
            }
            extendedInterruption = false;
            if (connectionInterrupted) {
                connectionInterrupted = false;
                $rootScope.$broadcast("amb.connection.recovered");
            }
            connected.resolve();
        });
        var connectClosedEventId = ambClient.subscribeToEvent("connection.closed", function() {
            setInterrupted("amb.connection.closed");
        });
        var connectBrokenEventId = ambClient.subscribeToEvent("connection.broken", function() {
            setInterrupted("amb.connection.broken");
        });
        jQuery(window).unload(function fixMemoryLeakInGlobalAMBEventManager(event) {
            ambClient.unsubscribeFromEvent(connectOpenedEventId);
            ambClient.unsubscribeFromEvent(connectClosedEventId);
            ambClient.unsubscribeFromEvent(connectBrokenEventId);
            jQuery(this).unbind(event);
        });
        ambClient.connect();
        return {
            getServerConnection: function() {
                return ambClient.getServerConnection();
            },
            connect: function() {
                ambClient.connect();
                return connected.promise;
            },
            get interrupted() {
                return ambInterrupted();
            },
            get extendedInterruption() {
                return extendedInterruption;
            },
            get connected() {
                return connected.promise;
            },
            abort: function() {
                ambClient.abort();
            },
            disconnect: function() {
                ambClient.disconnect();
            },
            getConnectionState: function() {
                return ambClient.getConnectionState();
            },
            getClientId: function() {
                return ambClient.getClientId();
            },
            getChannel: function(channelName) {
                var channel = ambClient.getChannel0(channelName);
                var originalSubscribe = channel.subscribe;
                var originalUnsubscribe = channel.unsubscribe;
                channel.subscribe = function(listener) {
                    originalSubscribe.call(channel, listener);
                    jQuery(window).unload(function() {
                        originalUnsubscribe.call(channel);
                    });
                    return channel;
                };
                return channel;
            },
            registerExtension: function(extensionName, extension) {
                ambClient.registerExtension(extensionName, extension);
            },
            unregisterExtension: function(extensionName) {
                ambClient.unregisterExtension(extensionName);
            },
            batch: function(batch) {
                ambClient.batch(batch);
            },
            getState: function() {
                return ambClient.getState();
            },
            getFilterString: function(filter) {
                filter = filter.
                replace(/\^EQ/g, '').
                replace(/\^ORDERBY(?:DESC)?[^^]*/g, '').
                replace(/^GOTO/, '');
                return btoa(filter).replace(/=/g, '-');
            },
            getChannelRW: function(table, filter) {
                var t = '/rw/default/' + table + '/' + this.getFilterString(filter);
                return this.getChannel(t);
            },
            isLoggedIn: function() {
                return ambClient.isLoggedIn();
            },
            subscribeToEvent: function(event, callback) {
                ambClient.subscribeToEvent(event, callback);
            },
            getConnectionEvents: function() {
                return ambClient.getConnectionEvents();
            },
            getEvents: function() {
                return ambClient.getConnectionEvents();
            },
            loginComplete: function() {
                ambClient.loginComplete();
            }
        };
    });;
    /*! RESOURCE: /scripts/app.ng.amb/controller.AMBRecordWatcher.js */
    angular.module("ng.amb").controller("AMBRecordWatcher", function($scope, $timeout, $window) {
        "use strict";
        var amb = $window.top.g_ambClient;
        $scope.messages = [];
        var lastFilter;
        var watcherChannel;
        var watcher;
    
        function onMessage(message) {
            $scope.messages.push(message.data);
        }
        $scope.getState = function() {
            return amb.getState();
        };
        $scope.initWatcher = function() {
            angular.element(":focus").blur();
            if (!$scope.filter || $scope.filter === lastFilter)
                return;
            lastFilter = $scope.filter;
            console.log("initiating watcher on " + $scope.filter);
            $scope.messages = [];
            if (watcher) {
                watcher.unsubscribe();
            }
            var base64EncodeQuery = btoa($scope.filter).replace(/=/g, '-');
            var channelId = '/rw/' + base64EncodeQuery;
            watcherChannel = amb.getChannel(channelId)
            watcher = watcherChannel.subscribe(onMessage);
        };
        amb.connect();
    });
    /*! RESOURCE: /scripts/app.ng.amb/factory.snRecordWatcher.js */
    angular.module("ng.amb").factory('snRecordWatcher', function($rootScope, amb, $timeout, snPresence, $log, urlTools) {
        "use strict";
        var watcherChannel;
        var connected = false;
        var diagnosticLog = true;
    
        function initWatcher(table, sys_id, query) {
            if (!table)
                return;
            if (sys_id)
                var filter = "sys_id=" + sys_id;
            else
                filter = query;
            if (!filter)
                return;
            return initChannel(table, filter);
        }
    
        function initList(table, query) {
            if (!table)
                return;
            query = query || "sys_idISNOTEMPTY";
            return initChannel(table, query);
        }
    
        function initTaskList(list, prevChannel) {
            if (prevChannel)
                prevChannel.unsubscribe();
            var sys_ids = list.toString();
            var filter = "sys_idIN" + sys_ids;
            return initChannel("task", filter);
        }
    
        function initChannel(table, filter) {
            if (isBlockedTable(table)) {
                $log.log("Blocked from watching", table);
                return null;
            }
            if (diagnosticLog)
                log(">>> init " + table + "?" + filter);
            watcherChannel = amb.getChannelRW(table, filter);
            watcherChannel.subscribe(onMessage);
            amb.connect();
            return watcherChannel;
        }
    
        function onMessage(message) {
            var r = message.data;
            var c = message.channel;
            if (diagnosticLog)
                log(">>> record " + r.operation + ": " + r.table_name + "." + r.sys_id + " " + r.display_value);
            $rootScope.$broadcast('record.updated', r);
            $rootScope.$broadcast("sn.stream.tap");
            $rootScope.$broadcast('list.updated', r, c);
        }
    
        function log(message) {
            $log.log(message);
        }
    
        function isBlockedTable(table) {
            return table == 'sys_amb_message' || table.startsWith('sys_rw');
        }
        return {
            initTaskList: initTaskList,
            initChannel: initChannel,
            init: function() {
                var location = urlTools.parseQueryString(window.location.search);
                var table = location['table'] || location['sysparm_table'];
                var sys_id = location['sys_id'] || location['sysparm_sys_id'];
                var query = location['sysparm_query'];
                initWatcher(table, sys_id, query);
                snPresence.init(table, sys_id, query);
            },
            initList: initList,
            initRecord: function(table, sysId) {
                initWatcher(table, sysId, null);
                snPresence.initWithDocument(table, sysId);
            }
        }
    });;
    /*! RESOURCE: /scripts/app.ng.amb/factory.AMBOverlay.js */
    angular.module("ng.amb").factory("AMBOverlay", function($templateCache, $compile, $rootScope) {
        "use strict";
        var showCallbacks = [],
            hideCallbacks = [],
            isRendered = false,
            modal,
            modalScope,
            modalOptions;
        var defaults = {
            backdrop: 'static',
            keyboard: false,
            show: true
        };
    
        function AMBOverlay(config) {
            config = config || {};
            if (angular.isFunction(config.onShow))
                showCallbacks.push(config.onShow);
            if (angular.isFunction(config.onHide))
                hideCallbacks.push(config.onHide);
    
            function lazyRender() {
                if (!angular.element('html')['modal']) {
                    var bootstrapInclude = "/scripts/bootstrap3/bootstrap.js";
                    ScriptLoader.getScripts([bootstrapInclude], renderModal);
                } else
                    renderModal();
            }
    
            function renderModal() {
                if (isRendered)
                    return;
                modalScope = angular.extend($rootScope.$new(), config);
                modal = $compile($templateCache.get("amb_disconnect_modal.xml"))(modalScope);
                angular.element("body").append(modal);
                modal.on("shown.bs.modal", function(e) {
                    for (var i = 0, len = showCallbacks.length; i < len; i++)
                        showCallbacks[i](e);
                });
                modal.on("hidden.bs.modal", function(e) {
                    for (var i = 0, len = hideCallbacks.length; i < len; i++)
                        hideCallbacks[i](e);
                });
                modalOptions = angular.extend({}, defaults, config);
                modal.modal(modalOptions);
                isRendered = true;
            }
    
            function showModal() {
                if (isRendered)
                    modal.modal('show');
            }
    
            function hideModal() {
                if (isRendered)
                    modal.modal('hide');
            }
    
            function destroyModal() {
                if (!isRendered)
                    return;
                modal.modal('hide');
                modal.remove();
                modalScope.$destroy();
                modalScope = void(0);
                isRendered = false;
                var pos = showCallbacks.indexOf(config.onShow);
                if (pos >= 0)
                    showCallbacks.splice(pos, 1);
                pos = hideCallbacks.indexOf(config.onShow);
                if (pos >= 0)
                    hideCallbacks.splice(pos, 1);
            }
            return {
                render: lazyRender,
                destroy: destroyModal,
                show: showModal,
                hide: hideModal,
                isVisible: function() {
                    if (!isRendered)
                        false;
                    return modal.visible();
                }
            }
        }
        $templateCache.put('amb_disconnect_modal.xml',
            '<div id="amb_disconnect_modal" tabindex="-1" aria-hidden="true" class="modal" role="dialog">' +
            '	<div class="modal-dialog small-modal" style="width:450px">' +
            '		<div class="modal-content">' +
            '			<header class="modal-header">' +
            '				<h4 id="small_modal1_title" class="modal-title">{{title || "Login"}}</h4>' +
            '			</header>' +
            '			<div class="modal-body">' +
            '			<iframe class="concourse_modal" ng-src=\'{{iframe || "/amb_login.do"}}\' frameborder="0" scrolling="no" height="400px" width="405px"></iframe>' +
            '			</div>' +
            '		</div>' +
            '	</div>' +
            '</div>'
        );
        return AMBOverlay;
    });;;
    /*! RESOURCE: /scripts/sn/common/presence/_module.js */
    angular.module('sn.common.presence', ['ng.amb', 'sn.common.glide']).config(function($provide) {
        "use strict";
        $provide.constant("PRESENCE_DISABLED", "false" === "true");
    });;
    /*! RESOURCE: /scripts/sn/common/presence/factory.snPresence.js */
    angular.module("sn.common.presence").factory('snPresence', function($rootScope, $window, $log, amb, $timeout, $http, snRecordPresence, snTabActivity, urlTools, PRESENCE_DISABLED) {
        "use strict";
        var REST = {
            PRESENCE: "/api/now/ui/presence"
        };
        var databaseInterval = ($window.NOW.presence_interval || 15) * 1000;
        var initialized = false;
        var primary = false;
        var presenceArray = [];
        var serverTimeMillis;
        var skew = 0;
        var st = 0;
    
        function init() {
            var location = urlTools.parseQueryString(window.location.search);
            var table = location['table'] || location['sysparm_table'];
            var sys_id = location['sys_id'] || location['sysparm_sys_id'];
            var query = location['sysparm_query'];
            initPresence(table, sys_id, query);
        }
    
        function initPresence(t, id) {
            if (PRESENCE_DISABLED)
                return;
            if (!initialized) {
                initialized = true;
                initRootScopes();
                if (!primary) {
                    CustomEvent.observe('sn.presence', onPresenceEvent);
                    CustomEvent.fireTop('sn.presence.ping');
                } else {
                    presenceArray = getLocalPresence();
                    if (presenceArray)
                        $timeout(schedulePresence, 100);
                    else
                        updateDatabase();
                }
            }
            snRecordPresence.initPresence(t, id);
        }
    
        function onPresenceEvent(parms) {
            presenceArray = parms;
            $timeout(broadcastPresence);
        }
    
        function initRootScopes() {
            if ($window.NOW.presence_scopes) {
                var ps = $window.NOW.presence_scopes;
                if (ps.indexOf($rootScope) == -1)
                    ps.push($rootScope);
            } else {
                $window.NOW.presence_scopes = [$rootScope];
                primary = CustomEvent.isTopWindow();
            }
        }
    
        function updateDatabase() {
            presenceArray = getLocalPresence();
            if (presenceArray) {
                determineStatus();
                $timeout(schedulePresence);
                return;
            }
            if (!amb.isLoggedIn() || !snTabActivity.isPrimary) {
                $timeout(schedulePresence);
                return;
            }
            var p = {
                user_agent: navigator.userAgent,
                ua_time: new Date().toISOString(),
                href: window.location.href,
                pathname: window.location.pathname,
                search: window.location.search,
                path: window.location.pathname + window.location.search
            };
            st = new Date().getTime();
            $http.post(REST.PRESENCE + '?sysparm_auto_request=true&cd=' + st, p).success(function(data) {
                var rt = new Date().getTime() - st;
                if (rt > 500)
                    console.log("snPresence response time " + rt + "ms");
                if (data.result && data.result.presenceArray) {
                    presenceArray = data.result.presenceArray;
                    setLocalPresence(presenceArray);
                    serverTimeMillis = data.result.serverTimeMillis;
                    skew = new Date().getTime() - serverTimeMillis;
                    var t = Math.floor(skew / 1000);
                    if (t < -15)
                        console.log(">>>>> server ahead " + Math.abs(t) + " seconds");
                    else if (t > 15)
                        console.log(">>>>> browser time ahead " + t + " seconds");
                }
                schedulePresence();
            }).error(function(response, status) {
                console.log("snPresence " + status);
                if (429 == status)
                    $timeout(updateDatabase, databaseInterval);
                else
                    schedulePresence();
            })
        }
    
        function schedulePresence() {
            $timeout(updateDatabase, databaseInterval);
            determineStatus();
            broadcastPresence();
        }
    
        function broadcastPresence() {
            $rootScope.$broadcast("sn.presence", presenceArray);
            if (!primary)
                return;
            CustomEvent.fireAll('sn.presence', presenceArray);
        }
    
        function determineStatus() {
            if (!presenceArray || !presenceArray.forEach) {
                $log.log("factory.snPresence >>> server error @ " + new Date());
                return;
            }
            var t = new Date().getTime();
            t -= skew;
            presenceArray.forEach(function(p) {
                var x = 0 + p.last_on;
                var y = t - x;
                p.status = "online";
                if (y > (5 * databaseInterval))
                    p.status = "offline";
                else if (y > (3 * databaseInterval))
                    p.status = "probably offline";
                else if (y > (2.5 * databaseInterval))
                    p.status = "maybe offline";
            })
        }
    
        function setLocalPresence(value) {
            var p = {
                saved: new Date().getTime(),
                presenceArray: value
            }
            $window.localStorage.setItem('snPresence', angular.toJson(p));
        }
    
        function getLocalPresence() {
            var p = $window.localStorage.getItem('snPresence');
            if (!p)
                return null;
            try {
                p = angular.fromJson(p);
            } catch (e) {
                p = {};
            }
            if (!p.presenceArray)
                return null;
            var now = new Date().getTime();
            if (now - p.saved >= databaseInterval)
                return null;
            return p.presenceArray;
        }
        return {
            init: init,
            initWithDocument: initPresence,
            initPresence: initPresence
        }
    });;
    /*! RESOURCE: /scripts/sn/common/presence/factory.snRecordPresence.js */
    angular.module("sn.common.presence").factory('snRecordPresence', function($rootScope, $location, amb, $timeout, $window, PRESENCE_DISABLED, snTabActivity) {
        "use strict";
        var statChannel;
        var interval = 20 * 1000;
        var sessions = {};
        var timer;
        var primary = false;
        var table;
        var sys_id;
    
        function initPresence(t, id) {
            if (PRESENCE_DISABLED)
                return;
            if (!t || !id)
                return;
            if (t == table && id == sys_id)
                return;
            initRootScopes();
            if (!primary)
                return;
            termPresence();
            table = t;
            sys_id = id;
            var recordPresence = "/sn/rp/" + table + "/" + sys_id;
            $rootScope.me = NOW.session_id;
            statChannel = amb.getChannel(recordPresence);
            statChannel.subscribe(onStatus);
            amb.connected.then(function() {
                setStatus("entered");
                $rootScope.status = "viewing";
            });
            timer = $timeout(managePresence, interval);
            return statChannel;
        }
    
        function initRootScopes() {
            if ($window.NOW.record_presence_scopes) {
                var ps = $window.NOW.record_presence_scopes;
                if (ps.indexOf($rootScope) == -1) {
                    ps.push($rootScope);
                    CustomEvent.observe('sn.sessions', onPresenceEvent);
                }
            } else {
                $window.NOW.record_presence_scopes = [$rootScope];
                primary = true;
            }
        }
    
        function onPresenceEvent(sessionsToSend) {
            $rootScope.$broadcast("sn.sessions", sessionsToSend);
            $rootScope.$broadcast("sp.sessions", sessionsToSend);
        }
    
        function termPresence() {
            if (timer)
                $timeout.cancel(timer);
            if (!statChannel)
                return;
            publish("exited");
            statChannel.unsubscribe();
            statChannel = table = sys_id = null;
        }
    
        function setStatus(status) {
            if (status == $rootScope.status)
                return;
            $rootScope.status = status;
            publish($rootScope.status);
        }
    
        function publish(status) {
            if (!statChannel)
                return;
            if (amb.getState() !== "opened")
                return;
            statChannel.publish({
                status: status,
                session_id: NOW.session_id,
                user_name: NOW.user_name,
                user_id: NOW.user_id,
                user_display_name: NOW.user_display_name,
                user_initials: NOW.user_initials,
                user_avatar: NOW.user_avatar,
                ua: navigator.userAgent,
                table: table,
                sys_id: sys_id,
                time: new Date().toString().substring(0, 24)
            });
        }
    
        function onStatus(message) {
            var d = message.data;
            if (d.session_id == NOW.session_id)
                return;
            var s = sessions[d.session_id];
            if (s)
                angular.extend(s, d);
            else
                s = sessions[d.session_id] = d;
            s.lastUpdated = new Date();
            broadcastSessions();
            if (s.status == 'entered')
                publish($rootScope.status);
        }
    
        function managePresence() {
            var now = new Date().getTime();
            var deleted = false;
            Object.keys(sessions).forEach(function(id) {
                var s = sessions[id];
                if (!s.lastUpdated)
                    return;
                var last = s.lastUpdated.getTime();
                var t = now - last;
                s.lastSeen = t / 1000;
                if (s.status === 'exited') {
                    deleted = true;
                    delete sessions[id];
                }
                if (t > interval * 2)
                    s.status = 'probably left';
                if (t > interval * 4) {
                    deleted = true;
                    delete sessions[id];
                }
            });
            if (Object.keys(sessions).length !== 0)
                publish($rootScope.status);
            timer = $timeout(managePresence, interval);
            if (deleted)
                broadcastSessions();
        }
    
        function broadcastSessions() {
            var sessionsToSend = getUniqueSessions();
            $rootScope.$broadcast("sn.sessions", sessionsToSend);
            $rootScope.$broadcast("sp.sessions", sessionsToSend);
            if (primary)
                $timeout(function() {
                    CustomEvent.fire('sn.sessions', sessionsToSend);
                })
        }
    
        function getUniqueSessions() {
            var uniqueSessionsByUser = {};
            var sessionKeys = Object.keys(sessions);
            sessionKeys.forEach(function(key) {
                var session = sessions[key];
                if (session.user_id == NOW.user_id)
                    return;
                if (session.user_id in uniqueSessionsByUser) {
                    var otherSession = uniqueSessionsByUser[session.user_id];
                    var thisPrecedence = getStatusPrecedence(session.status);
                    var otherPrecedence = getStatusPrecedence(otherSession.status);
                    uniqueSessionsByUser[session.user_id] = thisPrecedence < otherPrecedence ? session : otherSession;
                    return
                }
                uniqueSessionsByUser[session.user_id] = session;
            });
            var uniqueSessions = {};
            angular.forEach(uniqueSessionsByUser, function(item) {
                uniqueSessions[item.session_id] = item;
            });
            return uniqueSessions;
        }
    
        function getStatusPrecedence(status) {
            switch (status) {
                case 'typing':
                    return 0;
                case 'viewing':
                    return 1;
                case 'entered':
                    return 2;
                case 'exited':
                case 'probably left':
                    return 4;
                case 'offline':
                    return 5;
                default:
                    return 3;
            }
        }
        $rootScope.$on("record.typing", function(evt, data) {
            setStatus(data.status);
        });
        var idleTable, idleSysID;
        snTabActivity.onIdle({
            onIdle: function RecordPresenceTabIdle() {
                idleTable = table;
                idleSysID = sys_id;
                sessions = {};
                termPresence();
                broadcastSessions();
            },
            onReturn: function RecordPresenceTabActive() {
                initPresence(idleTable, idleSysID, true);
                idleTable = idleSysID = void(0);
            },
            delay: interval * 4
        });
        return {
            initPresence: initPresence,
            termPresence: termPresence
        }
    });;
    /*! RESOURCE: /scripts/sn/common/presence/directive.snPresence.js */
    angular.module('sn.common.presence').directive('snPresence', function(snPresence, $rootScope, $timeout) {
        'use strict';
        $timeout(snPresence.init, 100);
        var presences = {};
        $rootScope.$on('sn.presence', function(event, presenceArray) {
            if (!presenceArray) {
                angular.forEach(presences, function(p) {
                    p.status = "offline";
                });
                return;
            }
            presenceArray.forEach(function(presence) {
                presences[presence.user] = presence;
            });
        });
        return {
            restrict: 'EA',
            replace: false,
            scope: {
                snPresence: '=',
                user: '='
            },
            link: function(scope, element) {
                if (!element.hasClass('presence'))
                    element.addClass('presence');
    
                function updatePresence() {
                    var id = scope.snPresence || scope.user;
                    if (presences[id]) {
                        var status = presences[id].status;
                        if (status === 'maybe offline' || status === 'probably offline') {
                            element.removeClass('presence-online presence-offline presence-away');
                            element.addClass('presence-away');
                        } else if (status == "offline" && !element.hasClass('presence-offline')) {
                            element.removeClass('presence-online presence-away');
                            element.addClass('presence-offline');
                        } else if ((status == "online" || status == "entered" || status == "viewing") && !element.hasClass('presence-online')) {
                            element.removeClass('presence-offline presence-away');
                            element.addClass('presence-online');
                        }
                    } else {
                        if (!element.hasClass('presence-offline'))
                            element.addClass('presence-offline');
                    }
                }
                $rootScope.$on('sn.presence', updatePresence);
                updatePresence();
            }
        };
    });;;
    /*! RESOURCE: /scripts/sn/common/user_profile/js_includes_user_profile.js */
    /*! RESOURCE: /scripts/sn/common/user_profile/_module.js */
    angular.module("sn.common.user_profile", []);;
    /*! RESOURCE: /scripts/sn/common/user_profile/directive.snUserProfile.js */
    angular.module('sn.common.user_profile').directive('snUserProfile', function(getTemplateUrl, snCustomEvent, $window, avatarProfilePersister) {
        "use strict";
        return {
            replace: true,
            restrict: 'E',
            templateUrl: getTemplateUrl('snUserProfile.xml'),
            scope: {
                profile: "=",
                showDirectMessagePrompt: "="
            },
            link: function(scope) {
                scope.showDirectMessagePromptFn = function() {
                    if (scope.showDirectMessagePrompt) {
                        var activeUserID = $window.NOW.user_id || "";
                        return !(!scope.profile ||
                            activeUserID === scope.profile.sysID ||
                            (scope.profile.document && activeUserID === scope.profile.document));
                    } else {
                        return false;
                    }
                };
            },
            controller: function($scope, snConnectService) {
                if ($scope.profile && $scope.profile.userID && avatarProfilePersister.getAvatar($scope.profile.userID))
                    $scope.profile = avatarProfilePersister.getAvatar($scope.profile.userID);
                $scope.$emit("sn-user-profile.ready");
                $scope.openDirectMessageConversation = function(evt) {
                    if (evt.keyCode === 9)
                        return;
                    snConnectService.openWithProfile($scope.profile);
                };
            }
        }
    });;;
    /*! RESOURCE: /scripts/sn/common/avatar/_module.js */
    angular.module('sn.common.avatar', ['sn.common.presence', 'sn.common.messaging', 'sn.common.user_profile']).config(function($provide) {
        $provide.value("liveProfileID", '');
    });;
    /*! RESOURCE: /scripts/sn/common/avatar/directive.snAvatarPopover.js */
    angular.module('sn.common.avatar').directive('snAvatarPopover', function($http, $compile, getTemplateUrl, avatarProfilePersister, $injector) {
        'use strict';
        return {
            restrict: 'E',
            templateUrl: getTemplateUrl('sn_avatar_popover.xml'),
            replace: true,
            transclude: true,
            scope: {
                members: '=',
                primary: '=?',
                showPresence: '=?',
                enableContextMenu: '=?',
                enableTooltip: '=?',
                enableBindOnce: '@',
                displayMemberCount: "=?",
                groupAvatar: "@",
                nopopover: "=",
                directconversation: '@',
                conversation: '@',
                primaryNonAssign: '=?'
            },
            compile: function(tElement) {
                var template = tElement.html();
                return function(scope, element, attrs, controller, transcludeFn) {
                    if (scope.directconversation) {
                        if (scope.directconversation === "true")
                            scope.directconversation = true;
                        else
                            scope.directconversation = false;
                        scope.showdirectconversation = !scope.directconversation;
                    } else {
                        scope.showdirectconversation = true;
                    }
                    if ($injector.has('inSupportClient') && $injector.get('inSupportClient'))
                        scope.showdirectconversation = false;
                    if (scope.primaryNonAssign) {
                        scope.primary = angular.extend({}, scope.primary, scope.primaryNonAssign);
                        if (scope.users && scope.users[0])
                            scope.users[0] = scope.primary;
                    }
    
                    function recompile() {
                        if (scope.primaryNonAssign) {
                            scope.primary = angular.extend({}, scope.primary, scope.primaryNonAssign);
                            if (scope.users && scope.users[0])
                                scope.users[0] = scope.primary;
                        }
                        var newElement = $compile(template, transcludeFn)(scope);
                        element.html(newElement);
                        if (scope.enableTooltip) {
                            element.tooltip({
                                placement: 'auto top',
                                container: 'body'
                            }).attr('data-original-title', scope.users[0].name).tooltip('fixTitle');
                            if (element.hideFix)
                                element.hideFix();
                        }
                    }
                    if (attrs.enableBindOnce === 'false') {
                        scope.$watch('primary', recompile);
                        scope.$watch('primaryNonAssign', recompile);
                        scope.$watch('members', recompile);
                    }
                    if (scope.enableTooltip && scope.nopopover) {
                        var usersWatch = scope.$watch('users', function() {
                            if (scope.users && scope.users.length === 1 && scope.users[0] && scope.users[0].name) {
                                element.tooltip({
                                    placement: 'auto top',
                                    container: 'body'
                                }).attr('data-original-title', scope.users[0].name).tooltip('fixTitle');
                                if (element.hideFix)
                                    element.hideFix();
                                usersWatch();
                            }
                        });
                    }
                };
            },
            controller: function($scope, liveProfileID, $timeout, $element, $document, snCustomEvent) {
                $scope.randId = Math.random();
                $scope.loadEvent = 'sn-user-profile.ready';
                $scope.closeEvent = ['chat:open_conversation', 'snAvatar.closePopover', 'body_clicked'];
                $scope.popoverConfig = {
                    template: '<div class="popover" role="tooltip"><div class="arrow"></div><div class="popover-content"></div></div>'
                };
                $scope.displayMemberCount = $scope.displayMemberCount || false;
                $scope.liveProfileID = liveProfileID;
                if ($scope.primaryNonAssign) {
                    $scope.primary = angular.extend({}, $scope.primary, $scope.primaryNonAssign);
                    if ($scope.users && $scope.users[0])
                        $scope.users[0] = $scope.primary;
                }
                $scope.$watch('members', function(newVal, oldVal) {
                    if (newVal === oldVal)
                        return;
                    if ($scope.members)
                        buildAvatar();
                });
                $scope.noPopover = function() {
                    $scope.popoverCursor = ($scope.nopopover || ($scope.members && $scope.members.length > 2)) ? "default" : "pointer";
                    return ($scope.nopopover || ($scope.members && $scope.members.length > 2));
                }
                $scope.avatarType = function() {
                    var result = [];
                    if ($scope.groupAvatar || !$scope.users)
                        return result;
                    if ($scope.users.length > 1)
                        result.push("group")
                    if ($scope.users.length === 2)
                        result.push("avatar-duo")
                    if ($scope.users.length === 3)
                        result.push("avatar-trio")
                    if ($scope.users.length >= 4)
                        result.push("avatar-quad")
                    return result;
                }
                $scope.getBackgroundStyle = function(user) {
                    var avatar = (user ? user.avatar : '');
                    if ($scope.groupAvatar)
                        avatar = $scope.groupAvatar;
                    if (avatar && avatar !== '')
                        return {
                            'background-image': 'url(' + avatar + ')'
                        };
                    if (user && user.name)
                        return '';
                    return void(0);
                };
                $scope.stopPropCheck = function(evt) {
                    $scope.$broadcast("snAvatar.closeOtherPopovers", $scope.randId);
                    if (!$scope.nopopover) {
                        evt.stopPropagation();
                    }
                };
                $scope.$on("snAvatar.closeOtherPopovers", function(id) {
                    if (id !== $scope.randId)
                        snCustomEvent.fireTop('snAvatar.closePopover');
                });
                $scope.maxStringWidth = function() {
                    var paddedWidth = parseInt($scope.avatarWidth * 0.8, 10);
                    return $scope.users.length === 1 ? paddedWidth : paddedWidth / 2;
                };
    
                function buildInitials(name) {
                    if (!name)
                        return "--";
                    var initials = name.split(" ").map(function(word) {
                        return word.toUpperCase();
                    }).filter(function(word) {
                        return word.match(/^[A-Z]/);
                    }).map(function(word) {
                        return word.substring(0, 1);
                    }).join("");
                    return (initials.length > 3) ?
                        initials.substr(0, 3) :
                        initials;
                }
                $scope.avatartooltip = function() {
                    if (!$scope.enableTooltip) {
                        return '';
                    }
                    if (!$scope.users) {
                        return '';
                    }
                    var names = [];
                    $scope.users.forEach(function(user) {
                        if (!user) {
                            return;
                        }
                        names.push(user.name);
                    });
                    return names.join(', ');
                };
    
                function buildAvatar() {
                    if (typeof $scope.primary === 'string') {
                        $http.get('/api/now/live/profiles/sys_user.' + $scope.primary).then(function(response) {
                            $scope.users = [{
                                userID: $scope.primary,
                                name: response.data.result.name,
                                initials: buildInitials(response.data.result.name),
                                avatar: response.data.result.avatar
                            }];
                            $scope.presenceEnabled = $scope.showPresence && !$scope.isDocument && $scope.users.length === 1;
                        });
                        return;
                    }
                    if ($scope.primary) {
                        if ($scope.primary.userImage)
                            $scope.primary.avatar = $scope.primary.userImage;
                        if (!$scope.primary.userID && $scope.primary.sys_id)
                            $scope.primary.userID = $scope.primary.sys_id;
                    }
                    $scope.isDocument = $scope.primary && $scope.primary.table && $scope.primary.table !== "sys_user" && $scope.primary.table !== "chat_queue_entry";
                    $scope.users = [$scope.primary];
                    if ($scope.primary && (!$scope.members || $scope.members.length <= 0) && ($scope.primary.avatar || $scope.primary.initials) && $scope.isDocument) {
                        $scope.users = [$scope.primary];
                    } else if ($scope.members && $scope.members.length > 0) {
                        $scope.users = buildCompositeAvatar($scope.members);
                    }
                    $scope.presenceEnabled = $scope.showPresence && !$scope.isDocument && $scope.users.length === 1;
                }
    
                function buildCompositeAvatar(members) {
                    var currentUser = window.NOW.user ? window.NOW.user.userID : window.NOW.user_id;
                    var users = angular.isArray(members) ? members.slice() : [members];
                    users = users.sort(function(a, b) {
                        var aID = a.userID || a.document;
                        var bID = b.userID || b.document;
                        if (a.table === "chat_queue_entry")
                            return 1;
                        if (aID === currentUser)
                            return 1;
                        else if (bID === currentUser)
                            return -1;
                        return 0;
                    });
                    if (users.length === 2)
                        users = [users[0]];
                    if (users.length > 2 && $scope.primary && $scope.primary.name && $scope.primary.table === "sys_user") {
                        var index = -1;
                        angular.forEach(users, function(user, i) {
                            if (user.sys_id === $scope.primary.sys_id) {
                                index = i;
                            }
                        });
                        if (index > -1) {
                            users.splice(index, 1);
                        }
                        users.splice(1, 0, $scope.primary);
                    }
                    return users;
                }
                buildAvatar();
                $scope.loadFullProfile = function() {
                    if ($scope.primary && !$scope.primary.sys_id && !avatarProfilePersister.getAvatar($scope.primary.userID)) {
                        $http.get('/api/now/live/profiles/' + $scope.primary.userID).then(
                            function(response) {
                                try {
                                    angular.extend($scope.primary, response.data.result);
                                    avatarProfilePersister.setAvatar($scope.primary.userID, $scope.primary);
                                } catch (e) {}
                            });
                    }
                }
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/avatar/directive.snAvatar.js */
    angular.module('sn.common.avatar').directive('snAvatar', function($http, $compile, getTemplateUrl, snCustomEvent, snConnectService) {
        'use strict';
        return {
            restrict: 'E',
            templateUrl: getTemplateUrl('sn_avatar.xml'),
            replace: true,
            transclude: true,
            scope: {
                members: '=',
                primary: '=',
                showPresence: '=?',
                enableContextMenu: '=?',
                enableTooltip: '=?',
                enableBindOnce: '@',
                displayMemberCount: "=?",
                groupAvatar: "@"
            },
            compile: function(tElement) {
                var template = tElement.html();
                return function(scope, element, attrs, controller, transcludeFn) {
                    function recompile() {
                        var newElement = $compile(template, transcludeFn)(scope);
                        element.html(newElement);
                        if (scope.enableTooltip) {
                            element.tooltip({
                                placement: 'auto top',
                                container: 'body'
                            }).attr('data-original-title', scope.users[0].name).tooltip('fixTitle');
                            if (element.hideFix)
                                element.hideFix();
                        }
                    }
                    if (attrs.enableBindOnce === 'false') {
                        scope.$watch('primary', recompile);
                        scope.$watch('members', recompile);
                    }
                    if (scope.enableTooltip) {
                        var usersWatch = scope.$watch('users', function() {
                            if (scope.users && scope.users.length === 1 && scope.users[0] && scope.users[0].name) {
                                element.tooltip({
                                    placement: 'auto top',
                                    container: 'body'
                                }).attr('data-original-title', scope.users[0].name).tooltip('fixTitle');
                                if (element.hideFix)
                                    element.hideFix();
                                usersWatch();
                            }
                        });
                    }
                    if (scope.enableContextMenu !== false) {
                        scope.contextOptions = [];
                        var gUser = null;
                        try {
                            gUser = g_user;
                        } catch (err) {}
                        if (scope.users && scope.users.length === 1 && scope.users[0] && (scope.users[0].userID || scope.users[0].sys_id)) {
                            scope.contextOptions = [
                                ["Open user's profile", function() {
                                    if (scope.users && scope.users.length > 0) {
                                        window.open('/nav_to.do?uri=' + encodeURIComponent('sys_user.do?sys_id=' + scope.users[0].userID), '_blank');
                                    }
                                }]
                            ];
                            if ((gUser && scope.users[0].userID && scope.users[0].userID !== gUser.userID) ||
                                (scope.liveProfileID && scope.users[0] && scope.users[0].sysID !== scope.liveProfileID)) {
                                scope.contextOptions.push(["Open a new chat", function() {
                                    snConnectService.openWithProfile(scope.users[0]);
                                }]);
                            }
                        }
                    } else {
                        scope.contextOptions = [];
                    }
                };
            },
            controller: function($scope, liveProfileID) {
                $scope.displayMemberCount = $scope.displayMemberCount || false;
                $scope.liveProfileID = liveProfileID;
                $scope.$watch('primary', function(newValue, oldValue) {
                    if ($scope.primary && newValue !== oldValue) {
                        buildAvatar();
                        if ($scope.contextOptions.length > 0) {
                            $scope.contextOptions = [
                                ["Open user's profile", function() {
                                    if ($scope.users && $scope.users.length > 0) {
                                        window.location.href = 'sys_user.do?sys_id=' + $scope.users[0].userID || $scope.users[0].userID;
                                    }
                                }]
                            ];
                            var gUser = null;
                            try {
                                gUser = g_user;
                            } catch (err) {}
                            if ((!gUser && !liveProfileID) || ($scope.users && $scope.users.length === 1 && $scope.users[0])) {
                                if ((gUser && $scope.users[0].userID && $scope.users[0].userID !== gUser.userID) ||
                                    ($scope.liveProfileID && $scope.users[0] && $scope.users[0].sysID !== $scope.liveProfileID)) {
                                    $scope.contextOptions.push(["Open a new chat", function() {
                                        snConnectService.openWithProfile($scope.users[0]);
                                    }]);
                                }
                            }
                        }
                    }
                });
                $scope.$watch('members', function() {
                    if ($scope.members)
                        buildAvatar();
                });
                $scope.avatarType = function() {
                    var result = [];
                    if ($scope.groupAvatar || !$scope.users)
                        return result;
                    if ($scope.users.length > 1)
                        result.push("group");
                    if ($scope.users.length === 2)
                        result.push("avatar-duo");
                    if ($scope.users.length === 3)
                        result.push("avatar-trio");
                    if ($scope.users.length >= 4)
                        result.push("avatar-quad");
                    return result;
                };
                $scope.getBackgroundStyle = function(user) {
                    var avatar = (user ? user.avatar : '');
                    if ($scope.groupAvatar)
                        avatar = $scope.groupAvatar;
                    if (avatar && avatar !== '')
                        return {
                            'background-image': 'url(' + avatar + ')'
                        };
                    if (user && user.name)
                        return '';
                    return void(0);
                };
                $scope.maxStringWidth = function() {
                    var paddedWidth = parseInt($scope.avatarWidth * 0.8, 10);
                    return $scope.users.length === 1 ? paddedWidth : paddedWidth / 2;
                };
    
                function buildInitials(name) {
                    if (!name)
                        return "--";
                    var initials = name.split(" ").map(function(word) {
                        return word.toUpperCase();
                    }).filter(function(word) {
                        return word.match(/^[A-Z]/);
                    }).map(function(word) {
                        return word.substring(0, 1);
                    }).join("");
                    return (initials.length > 3) ?
                        initials.substr(0, 3) :
                        initials;
                }
                $scope.avatartooltip = function() {
                    if (!$scope.enableTooltip) {
                        return '';
                    }
                    if (!$scope.users) {
                        return '';
                    }
                    var names = [];
                    $scope.users.forEach(function(user) {
                        if (!user) {
                            return;
                        }
                        names.push(user.name);
                    });
                    return names.join(', ');
                };
    
                function buildAvatar() {
                    if (typeof $scope.primary === 'string') {
                        $http.get('/api/now/live/profiles/sys_user.' + $scope.primary).then(function(response) {
                            $scope.users = [{
                                userID: $scope.primary,
                                name: response.data.result.name,
                                initials: buildInitials(response.data.result.name),
                                avatar: response.data.result.avatar
                            }];
                            $scope.presenceEnabled = $scope.showPresence && !$scope.isDocument && $scope.users.length === 1;
                        });
                        return;
                    }
                    if ($scope.primary) {
                        if ($scope.primary.userImage)
                            $scope.primary.avatar = $scope.primary.userImage;
                        if (!$scope.primary.userID && $scope.primary.sys_id)
                            $scope.primary.userID = $scope.primary.sys_id;
                    }
                    $scope.isDocument = $scope.primary && $scope.primary.table && $scope.primary.table !== "sys_user" && $scope.primary.table !== "chat_queue_entry";
                    $scope.users = [$scope.primary];
                    if ($scope.primary && (!$scope.members || $scope.members.length <= 0) && ($scope.primary.avatar || $scope.primary.initials) && $scope.isDocument) {
                        $scope.users = [$scope.primary];
                    } else if ($scope.members && $scope.members.length > 0) {
                        $scope.users = buildCompositeAvatar($scope.members);
                    }
                    $scope.presenceEnabled = $scope.showPresence && !$scope.isDocument && $scope.users.length === 1;
                }
    
                function buildCompositeAvatar(members) {
                    var currentUser = window.NOW.user ? window.NOW.user.userID : window.NOW.user_id;
                    var users = angular.isArray(members) ? members.slice() : [members];
                    users = users.sort(function(a, b) {
                        var aID = a.userID || a.document;
                        var bID = b.userID || b.document;
                        if (a.table === "chat_queue_entry")
                            return 1;
                        if (aID === currentUser)
                            return 1;
                        else if (bID === currentUser)
                            return -1;
                        return 0;
                    });
                    if (users.length === 2)
                        users = [users[0]];
                    if (users.length > 2 && $scope.primary && $scope.primary.name && $scope.primary.table === "sys_user") {
                        var index = -1;
                        angular.forEach(users, function(user, i) {
                            if (user.sys_id === $scope.primary.sys_id) {
                                index = i;
                            }
                        });
                        if (index > -1) {
                            users.splice(index, 1);
                        }
                        users.splice(1, 0, $scope.primary);
                    }
                    return users;
                }
                buildAvatar();
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/avatar/service.avatarProfilePersister.js */
    angular.module('sn.common.avatar').service('avatarProfilePersister', function() {
        "use strict";
        var avatars = {};
    
        function setAvatar(id, payload) {
            avatars[id] = payload;
        }
    
        function getAvatar(id) {
            return avatars[id];
        }
        return {
            setAvatar: setAvatar,
            getAvatar: getAvatar
        }
    });;
    /*! RESOURCE: /scripts/sn/common/avatar/directive.snUserAvatar.js */
    angular.module('sn.common.avatar').directive('snUserAvatar', function(getTemplateUrl) {
        "use strict";
        return {
            restrict: 'E',
            templateUrl: getTemplateUrl('sn_user_avatar.xml'),
            replace: true,
            scope: {
                userId: '=',
                avatarUrl: '=',
                initials: '=',
                enablePresence: '@'
            },
            controller: function($scope) {
                $scope.enablePresence = $scope.enablePresence === 'true';
                $scope.getBackgroundStyle = function() {
                    if ($scope.avatarUrl && $scope.avatarUrl !== '')
                        return {
                            'background-image': 'url(' + $scope.avatarUrl + ')'
                        };
                    return '';
                };
            }
        }
    });;;
    /*! RESOURCE: /scripts/sn/common/controls/js_includes_controls.js */
    /*! RESOURCE: /scripts/sn/common/controls/_module.js */
    angular.module('sn.common.controls', []);;
    /*! RESOURCE: /scripts/sn/common/controls/directive.snChoiceList.js */
    angular.module('sn.common.controls').directive('snChoiceList', function($timeout) {
        "use strict";
        return {
            restrict: 'E',
            replace: true,
            scope: {
                snModel: "=",
                snTextField: "@",
                snValueField: "@",
                snOptions: "=?",
                snItems: "=?",
                snOnChange: "&",
                snDisabled: "=",
                snDialogName: "=",
            },
            template: '<select ng-disabled="snDisabled" ng-model="model" ng-options="item[snValueField] as item[snTextField] for item in snItems"><option value="" ng-show="snOptions.placeholder">{{snOptions.placeholder}}</option></select>',
            link: function(scope, element, attrs) {
                if (scope.snDialogName)
                    scope.$on("dialog." + scope.snDialogName + ".close", function() {
                        $timeout(function() {
                            $(element).select2("destroy");
                        })
                    });
                $(element).css("opacity", 0);
                var config = {
                    width: "100%"
                };
                if (scope.snOptions) {
                    if (scope.snOptions.placeholder) {
                        config.placeholderOption = "first";
                    }
                    if (scope.snOptions.hideSearch && scope.snOptions.hideSearch === true) {
                        config.minimumResultsForSearch = -1;
                    }
                }
    
                function init() {
                    scope.model = scope.snModel;
                    render();
                }
    
                function render() {
                    if (!attrs) {
                        $timeout(function() {
                            render();
                        });
                        return;
                    }
                    $timeout(function() {
                        $(element).css("opacity", 1);
                        $(element).select2("destroy");
                        $(element).select2(config);
                    });
                }
                init();
                scope.$watch("snItems", function(newValue, oldValue) {
                    if (newValue !== oldValue) {
                        init();
                    }
                }, true);
                scope.$watch("snModel", function(newValue) {
                    if (newValue !== undefined && newValue !== scope.model) {
                        init();
                    }
                });
                scope.$watch("model", function(newValue, oldValue) {
                    if (newValue !== oldValue) {
                        scope.snModel = newValue;
                        if (scope.snOnChange)
                            scope.snOnChange({
                                selectedValue: newValue
                            });
                    }
                });
            },
            controller: function($scope) {}
        }
    });;
    /*! RESOURCE: /scripts/sn/common/controls/directive.snReferencePicker.js */
    angular.module('sn.common.controls').directive('snReferencePicker', function($timeout, $http, urlTools, filterExpressionParser, $sanitize, i18n) {
        "use strict";
        return {
            restrict: 'E',
            replace: true,
            scope: {
                ed: "=?",
                field: "=",
                refTable: "=?",
                refId: "=?",
                snOptions: "=?",
                snOnChange: "&",
                snOnBlur: "&",
                snOnClose: "&",
                snOnOpen: '&',
                minimumInputLength: "@",
                snDisabled: "=",
                snPageSize: "@",
                dropdownCssClass: "@",
                formatResultCssClass: "&",
                overlay: "=",
                additionalDisplayColumns: "@",
                displayColumn: "@",
                recordValues: '&',
                getGlideForm: '&glideForm',
                domain: "@",
                snSelectWidth: '@',
            },
            template: '<input type="text" name="{{field.name}}" ng-disabled="snDisabled" style="min-width: 150px;" ng-model="field.displayValue" />',
            link: function(scope, element, attrs, ctrl) {
                scope.ed = scope.ed || scope.field.ed;
                scope.selectWidth = scope.snSelectWidth || '100%';
                element.css("opacity", 0);
                var fireReadyEvent = true;
                var g_form;
                if (angular.isDefined(scope.getGlideForm))
                    g_form = scope.getGlideForm();
                var fieldAttributes = {};
                if (angular.isDefined(scope.field) && angular.isDefined(scope.field.attributes) && typeof scope.ed.attributes == 'undefined')
                    if (Array.isArray(scope.field.attributes))
                        fieldAttributes = scope.field.attributes;
                    else
                        fieldAttributes = parseAttributes(scope.field.attributes);
                else
                    fieldAttributes = parseAttributes(scope.ed.attributes);
                if (!angular.isDefined(scope.additionalDisplayColumns) && angular.isDefined(fieldAttributes['ref_ac_columns']))
                    scope.additionalDisplayColumns = fieldAttributes['ref_ac_columns'];
                var select2AjaxHelpers = {
                    formatSelection: function(item) {
                        return $sanitize(getDisplayValue(item));
                    },
                    formatResult: function(item) {
                        var displayValues = getDisplayValues(item);
                        if (displayValues.length == 1)
                            return $sanitize(displayValues[0]);
                        if (displayValues.length > 1) {
                            var width = 100 / displayValues.length;
                            var markup = "";
                            for (var i = 0; i < displayValues.length; i++)
                                markup += "<div style='width: " + width + "%;' class='select2-result-cell'>" + $sanitize(displayValues[i]) + "</div>";
                            return markup;
                        }
                        return "";
                    },
                    search: function(queryParams) {
                        if ('sysparm_include_variables' in queryParams.data) {
                            var url = urlTools.getURL('ref_list_data', queryParams.data);
                            return $http.get(url).then(queryParams.success);
                        } else {
                            var url = urlTools.getURL('ref_list_data');
                            return $http.post(url, queryParams.data).then(queryParams.success);
                        }
                    },
                    initSelection: function(elem, callback) {
                        if (scope.field.displayValue)
                            callback({
                                sys_id: scope.field.value,
                                name: scope.field.displayValue
                            });
                    }
                };
                var config = {
                    width: scope.selectWidth,
                    minimumInputLength: scope.minimumInputLength ? parseInt(scope.minimumInputLength, 10) : 0,
                    overlay: scope.overlay,
                    containerCssClass: 'select2-reference ng-form-element',
                    placeholder: '   ',
                    formatSearching: '',
                    allowClear: attrs.allowClear !== 'false',
                    id: function(item) {
                        return item.sys_id;
                    },
                    sortResults: (scope.snOptions && scope.snOptions.sortResults) ? scope.snOptions.sortResults : undefined,
                    ajax: {
                        quietMillis: NOW.ac_wait_time,
                        data: function(filterText, page) {
                            var filterExpression = filterExpressionParser.parse(filterText, scope.ed.defaultOperator);
                            var colToSearch = getReferenceColumnToSearch();
                            var q = colToSearch + filterExpression.operator + filterExpression.filterText +
                                '^' + colToSearch + 'ISNOTEMPTY' + getExcludedValues() + "^EQ";
                            var params = {
                                start: (scope.pageSize * (page - 1)),
                                count: scope.pageSize,
                                sysparm_target_table: scope.refTable,
                                sysparm_target_sys_id: scope.refId,
                                sysparm_target_field: scope.ed.dependent_field || scope.ed.name,
                                table: scope.ed.reference,
                                qualifier: scope.ed.qualifier,
                                data_adapter: scope.ed.data_adapter,
                                attributes: scope.ed.attributes,
                                dependent_field: scope.ed.dependent_field,
                                dependent_table: scope.ed.dependent_table,
                                dependent_value: scope.ed.dependent_value,
                                p: scope.ed.reference + ';q:' + q + ';r:' + scope.ed.qualifier
                            };
                            if (scope.domain) {
                                params.sysparm_domain = scope.domain;
                            }
                            if (angular.isDefined(scope.field) && scope.field['_cat_variable'] === true) {
                                delete params['sysparm_target_table'];
                                params['sysparm_include_variables'] = true;
                                params['variable_ids'] = scope.field.sys_id;
                                var getFieldSequence = g_form.$private.options('getFieldSequence');
                                if (getFieldSequence) {
                                    params['variable_sequence1'] = getFieldSequence();
                                }
                                var itemSysId = g_form.$private.options('itemSysId');
                                params['sysparm_id'] = itemSysId;
                                var getFieldParams = g_form.$private.options('getFieldParams');
                                if (getFieldParams) {
                                    angular.extend(params, getFieldParams());
                                }
                            }
                            if (scope.recordValues)
                                params.sysparm_record_values = scope.recordValues();
                            return params;
                        },
                        results: function(data, page) {
                            return ctrl.filterResults(data, page, scope.pageSize);
                        },
                        transport: select2AjaxHelpers.search
                    },
                    formatSelection: select2AjaxHelpers.formatSelection,
                    formatResult: select2AjaxHelpers.formatResult,
                    initSelection: select2AjaxHelpers.initSelection,
                    dropdownCssClass: attrs.dropdownCssClass,
                    formatResultCssClass: scope.formatResultCssClass || null
                };
                if (scope.snOptions) {
                    if (scope.snOptions.placeholder) {
                        config.placeholder = scope.snOptions.placeholder;
                    }
                    if (scope.snOptions.width) {
                        config.width = scope.snOptions.width;
                    }
                }
    
                function getReferenceColumnToSearch() {
                    var colName = 'name';
                    if (scope.ed.searchField)
                        colName = scope.ed.searchField;
                    else if (fieldAttributes['ref_ac_columns_search'] == 'true' && 'ref_ac_columns' in fieldAttributes && fieldAttributes['ref_ac_columns'] != '') {
                        var refAcColumns = fieldAttributes['ref_ac_columns'].split(';');
                        colName = refAcColumns[0];
                    } else if (fieldAttributes['ref_ac_order_by'])
                        colName = fieldAttributes['ref_ac_order_by'];
                    return colName;
                }
    
                function getExcludedValues() {
                    if (scope.ed.excludeValues && scope.ed.excludeValues != '') {
                        return '^sys_idNOT IN' + scope.ed.excludeValues;
                    }
                    return '';
                }
    
                function parseAttributes(strAttributes) {
                    var attributeArray = (strAttributes && strAttributes.length ? strAttributes.split(',') : []);
                    var attributeObj = {};
                    for (var i = 0; i < attributeArray.length; i++) {
                        if (attributeArray[i].length > 0) {
                            var attribute = attributeArray[i].split('=');
                            attributeObj[attribute[0]] = attribute.length > 1 ? attribute[1] : '';
                        }
                    }
                    return attributeObj;
                }
    
                function init() {
                    scope.model = scope.snModel;
                    render();
                }
    
                function render() {
                    $timeout(function() {
                        i18n.getMessage('Searching...', function(searchingMsg) {
                            config.formatSearching = function() {
                                return searchingMsg;
                            };
                        });
                        element.css("opacity", 1);
                        element.select2("destroy");
                        var select2 = element.select2(config);
                        select2.bind("change", select2Change);
                        select2.bind("select2-removed", select2Change);
                        select2.bind("select2-blur", function() {
                            scope.$apply(function() {
                                scope.snOnBlur();
                            });
                        });
                        select2.bind("select2-close", function() {
                            scope.$apply(function() {
                                scope.snOnClose();
                            });
                        });
                        select2.bind("select2-open", function() {
                            scope.$apply(function() {
                                if (scope.snOnOpen)
                                    scope.snOnOpen();
                            });
                        });
                        if (fireReadyEvent) {
                            scope.$emit('select2.ready', element);
                            fireReadyEvent = false;
                        }
                    });
                }
    
                function select2Change(e) {
                    e.stopImmediatePropagation();
                    if (e.added) {
                        if (scope.$$phase || scope.$root.$$phase)
                            return;
                        var selectedItem = e.added;
                        var value = selectedItem.sys_id;
                        var displayValue = value ? getDisplayValue(selectedItem) : '';
                        if (scope.snOptions && scope.snOptions.useGlideForm === true) {
                            g_form.setValue(scope.field.name, value, displayValue);
                            scope.rowSelected();
                        } else {
                            scope.$apply(function() {
                                scope.field.value = value;
                                scope.field.displayValue = displayValue;
                                scope.rowSelected();
                            });
                        }
                        if (scope.snOnChange) {
                            e.displayValue = displayValue;
                            scope.snOnChange(e);
                        }
                    } else if (e.removed) {
                        if (scope.snOptions && scope.snOptions.useGlideForm === true) {
                            g_form.clearValue(scope.field.name);
                            if (scope.snOnChange)
                                scope.snOnChange(e);
                        } else {
                            scope.$apply(function() {
                                scope.field.displayValue = '';
                                scope.field.value = '';
                                if (scope.snOnChange)
                                    scope.snOnChange(e);
                            });
                        }
                    }
                }
    
                function getDisplayValue(selectedItem) {
                    var displayValue = '';
                    if (selectedItem && selectedItem.sys_id) {
                        if (scope.displayColumn && typeof selectedItem[scope.displayColumn] != "undefined")
                            displayValue = selectedItem[scope.displayColumn];
                        else if (selectedItem.$$displayValue)
                            displayValue = selectedItem.$$displayValue;
                        else if (selectedItem.name)
                            displayValue = selectedItem.name;
                        else if (selectedItem.title)
                            displayValue = selectedItem.title;
                    }
                    return displayValue;
                }
    
                function getDisplayValues(selectedItem) {
                    var displayValues = [];
                    if (selectedItem && selectedItem.sys_id) {
                        var current = "";
                        if (scope.displayColumn && typeof selectedItem[scope.displayColumn] != "undefined")
                            current = selectedItem[scope.displayColumn];
                        else if (selectedItem.$$displayValue)
                            current = selectedItem.$$displayValue;
                        else if (selectedItem.name)
                            current = selectedItem.name;
                        else if (selectedItem.title)
                            current = selectedItem.title;
                        displayValues.push(current);
                    }
                    if (scope.additionalDisplayColumns) {
                        var columns = scope.additionalDisplayColumns.split(",");
                        for (var i = 0; i < columns.length; i++) {
                            var column = columns[i];
                            if (selectedItem[column])
                                displayValues.push(selectedItem[column]);
                        }
                    }
                    return displayValues;
                }
                scope.$watch("field.displayValue", function(newValue, oldValue) {
                    if (newValue != oldValue && newValue !== scope.model) {
                        init();
                    }
                });
                scope.$on("snReferencePicker.activate", function(evt, parms) {
                    $timeout(function() {
                        element.select2("open");
                    })
                });
                init();
            },
            controller: function($scope, $rootScope) {
                $scope.pageSize = 20;
                if ($scope.snPageSize)
                    $scope.pageSize = parseInt($scope.snPageSize);
                $scope.rowSelected = function() {
                    $rootScope.$broadcast("@page.reference.selected", {
                        field: $scope.field,
                        ed: $scope.ed
                    });
                };
                this.filterResults = function(data, page) {
                    return {
                        results: data.data.items,
                        more: (page * $scope.pageSize < data.data.total)
                    };
                };
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/controls/directive.snRecordPicker.js */
    angular.module('sn.common.controls').directive('snRecordPicker', function($timeout, $http, urlTools, filterExpressionParser, $sanitize, i18n) {
        "use strict";
        var cache = {};
    
        function cleanLabel(val) {
            if (typeof val == "object")
                return "";
            return typeof val == "string" ? val.trim() : val;
        }
        return {
            restrict: 'E',
            replace: true,
            scope: {
                field: '=',
                table: '=',
                defaultQuery: '=?',
                searchFields: '=?',
                valueField: '=?',
                displayField: '=?',
                displayFields: '=?',
                pageSize: '=?',
                onChange: '&',
                snDisabled: '=',
                multiple: '=?',
                options: '=?',
                placeholder: '@'
            },
            template: '<input type="text" ng-disabled="snDisabled" style="min-width: 150px;" name="{{field.name}}" ng-model="field.value" />',
            controller: function($scope) {
                if (!angular.isNumber($scope.pageSize))
                    $scope.pageSize = 20;
                if (!angular.isDefined($scope.valueField))
                    $scope.valueField = 'sys_id';
                this.filterResults = function(data, page) {
                    return {
                        results: data.data.result,
                        more: (page * $scope.pageSize < parseInt(data.headers('x-total-count'), 10))
                    };
                };
            },
            link: function(scope, element, attrs, ctrl) {
                var isExecuting = false;
                var select2Helpers = {
                    formatSelection: function(item) {
                        return $sanitize(getDisplayValue(item));
                    },
                    formatResult: function(item) {
                        var displayFields = getdisplayFields(item);
                        if (displayFields.length == 1)
                            return $sanitize(cleanLabel(displayFields[0]));
                        if (displayFields.length > 1) {
                            var markup = $sanitize(displayFields[0]);
                            var width = 100 / (displayFields.length - 1);
                            markup += "<div>";
                            for (var i = 1; i < displayFields.length; i++)
                                markup += "<div style='width: " + width + "%;' class='select2-additional-display-field'>" + $sanitize(cleanLabel(displayFields[i])) + "</div>";
                            markup += "</div>";
                            return markup;
                        }
                        return "";
                    },
                    search: function(queryParams) {
                        var url = '/api/now/table/' + scope.table + '?' + urlTools.encodeURIParameters(queryParams.data);
                        if (scope.options && scope.options.cache && cache[url])
                            return queryParams.success(cache[url]);
                        return $http.get(url).then(function(response) {
                            if (scope.options && scope.options.cache) {
                                cache[url] = response;
                            }
                            return queryParams.success(response)
                        });
                    },
                    initSelection: function(elem, callback) {
                        if (scope.field.displayValue) {
                            if (scope.multiple) {
                                var items = [],
                                    sel;
                                var values = scope.field.value.split(',');
                                var displayValues = scope.field.displayValue.split(',');
                                for (var i = 0; i < values.length; i++) {
                                    sel = {};
                                    sel[scope.valueField] = values[i];
                                    sel[scope.displayField] = displayValues[i];
                                    items.push(sel);
                                }
                                callback(items);
                            } else {
                                var sel = {};
                                sel[scope.valueField] = scope.field.value;
                                sel[scope.displayField] = scope.field.displayValue;
                                callback(sel);
                            }
                        } else
                            callback([]);
                    }
                };
                var config = {
                    width: '100%',
                    containerCssClass: 'select2-reference ng-form-element',
                    placeholder: scope.placeholder || '    ',
                    formatSearching: '',
                    allowClear: (scope.options && typeof scope.options.allowClear !== "undefined") ? scope.options.allowClear : true,
                    id: function(item) {
                        return item[scope.valueField];
                    },
                    ajax: {
                        quietMillis: NOW.ac_wait_time,
                        data: function(filterText, page) {
                            var params = {
                                sysparm_offset: (scope.pageSize * (page - 1)),
                                sysparm_limit: scope.pageSize,
                                sysparm_query: buildQuery(filterText, scope.searchFields, scope.defaultQuery)
                            };
                            return params;
                        },
                        results: function(data, page) {
                            return ctrl.filterResults(data, page, scope.pageSize);
                        },
                        transport: select2Helpers.search
                    },
                    formatSelection: select2Helpers.formatSelection,
                    formatResult: select2Helpers.formatResult,
                    formatResultCssClass: function() {
                        return '';
                    },
                    initSelection: select2Helpers.initSelection,
                    multiple: scope.multiple
                };
    
                function buildQuery(filterText, searchFields, defaultQuery) {
                    var queryParts = [];
                    var operator = "CONTAINS";
                    if (filterText.startsWith("*"))
                        filterText = filterText.substring(1);
                    if (defaultQuery)
                        queryParts.push(defaultQuery);
                    var filterExpression = filterExpressionParser.parse(filterText, operator);
                    if (searchFields != null) {
                        var fields = searchFields.split(',');
                        if (filterExpression.filterText != '') {
                            var OR = "";
                            for (var i = 0; i < fields.length; i++) {
                                queryParts.push(OR + fields[i] + filterExpression.operator + filterExpression.filterText);
                                OR = "OR";
                            }
                        }
                        for (var i = 0; i < fields.length; i++)
                            queryParts.push('ORDERBY' + fields[i]);
                        queryParts.push('EQ');
                    }
                    return queryParts.join('^');
                }
                scope.field = scope.field || {};
                var initTimeout = null;
                var value = scope.field.value;
                var oldValue = scope.field.value;
                var $select;
    
                function init() {
                    element.css("opacity", 0);
                    $timeout.cancel(initTimeout);
                    initTimeout = $timeout(function() {
                        i18n.getMessage('Searching...', function(searchingMsg) {
                            config.formatSearching = function() {
                                return searchingMsg;
                            };
                        });
                        element.css("opacity", 1);
                        element.select2("destroy");
                        $select = element.select2(config);
                        $select.bind("change", onChanged);
                        $select.bind("select2-removed", onChanged);
                        $select.bind("select2-selecting", onSelecting);
                        $select.bind("select2-removing", onRemoving);
                        scope.$emit('select2.ready', element);
                    });
                }
    
                function onSelecting(e) {
                    isExecuting = true;
                    oldValue = scope.field.value;
                    var selectedItem = e.choice;
                    if (scope.multiple && selectedItem[scope.valueField] != '') {
                        var values = scope.field.value == '' ? [] : scope.field.value.split(',');
                        var displayValues = scope.field.displayValue == '' ? [] : scope.field.displayValue.split(',');
                        values.push(selectedItem[scope.valueField]);
                        displayValues.push(getDisplayValue(selectedItem));
                        scope.field.value = values.join(',');
                        scope.field.displayValue = displayValues.join(',');
                        e.preventDefault();
                        $select.select2('val', values).select2('close');
                        scope.$apply(function() {
                            callChange(oldValue, e);
                        });
                    }
                }
    
                function onRemoving(e) {
                    isExecuting = true;
                    oldValue = scope.field.value;
                    var removed = e.choice;
                    if (scope.multiple) {
                        var values = scope.field.value.split(',');
                        var displayValues = scope.field.displayValue.split(',');
                        for (var i = values.length - 1; i >= 0; i--) {
                            if (removed[scope.valueField] == values[i]) {
                                values.splice(i, 1);
                                displayValues.splice(i, 1);
                                break;
                            }
                        }
                        scope.field.value = values.join(',');
                        scope.field.displayValue = displayValues.join(',');
                        e.preventDefault();
                        $select.select2('val', scope.field.value.split(','));
                        scope.$apply(function() {
                            callChange(oldValue, e);
                        });
                    }
                }
    
                function callChange(oldValue, e) {
                    var f = scope.field;
                    var p = {
                        field: f,
                        newValue: f.value,
                        oldValue: oldValue,
                        displayValue: f.displayValue
                    }
                    scope.$emit("field.change", p);
                    scope.$emit("field.change." + f.name, p);
                    if (scope.onChange)
                        try {
                            scope.onChange(e);
                        } catch (ex) {
                            console.log("directive.snRecordPicker error in onChange")
                            console.log(ex)
                        }
                    isExecuting = false;
                }
    
                function onChanged(e) {
                    e.stopImmediatePropagation();
                    if (scope.$$phase || scope.$root.$$phase) {
                        console.warn('in digest, returning early');
                        return;
                    }
                    if (e.added) {
                        var selectedItem = e.added;
                        if (!scope.multiple) {
                            scope.field.value = selectedItem[scope.valueField];
                            if (scope.field.value) {
                                scope.field.displayValue = getDisplayValue(selectedItem);
                            } else
                                scope.field.displayValue = '';
                        }
                    } else if (e.removed) {
                        if (!scope.multiple) {
                            scope.field.displayValue = '';
                            scope.field.value = '';
                        }
                    }
                    scope.$apply(function() {
                        callChange(oldValue, e);
                    });
                }
    
                function getDisplayValue(selectedItem) {
                    var displayValue = selectedItem[scope.valueField];
                    if (selectedItem) {
                        if (scope.displayField && angular.isDefined(selectedItem[scope.displayField]))
                            displayValue = selectedItem[scope.displayField];
                        else if (selectedItem.name)
                            displayValue = selectedItem.name;
                        else if (selectedItem.title)
                            displayValue = selectedItem.title;
                    }
                    return cleanLabel(displayValue);
                }
    
                function getdisplayFields(selectedItem) {
                    var displayFields = [];
                    if (selectedItem && selectedItem[scope.valueField]) {
                        var current = "";
                        if (scope.displayField && angular.isDefined(selectedItem[scope.displayField]))
                            current = selectedItem[scope.displayField];
                        else if (selectedItem.name)
                            current = selectedItem.name;
                        else if (selectedItem.title)
                            current = selectedItem.title;
                        displayFields.push(current);
                    }
                    if (scope.displayFields) {
                        var columns = scope.displayFields.split(",");
                        for (var i = 0; i < columns.length; i++) {
                            var column = columns[i];
                            if (selectedItem[column])
                                displayFields.push(selectedItem[column]);
                        }
                    }
                    return displayFields;
                }
                scope.$watch("field.value", function(newValue) {
                    if (isExecuting) return;
                    if (angular.isDefined(newValue) && $select) {
                        if (scope.multiple)
                            $select.select2('val', newValue.split(',')).select2('close');
                        else
                            $select.select2('val', newValue).select2('close');
                    }
                });
                if (attrs.displayValue) {
                    attrs.$observe('displayValue', function(value) {
                        scope.field.value = value;
                    });
                }
                init();
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/controls/directive.snSelectBasic.js */
    angular.module('sn.common.controls').directive('snSelectBasic', function($timeout) {
        return {
            restrict: 'C',
            priority: 1,
            require: '?ngModel',
            scope: {
                'snAllowClear': '@',
                'snSelectWidth': '@',
                'snChoices': '=?'
            },
            link: function(scope, element, attrs, ngModel) {
                if (angular.isFunction(element.select2)) {
                    element.css("opacity", 0);
                    scope.selectWidth = scope.snSelectWidth || '100%';
                    scope.selectAllowClear = scope.snAllowClear === "true";
                    $timeout(function() {
                        element.css("opacity", 1);
                        element.select2({
                            allowClear: scope.selectAllowClear,
                            width: scope.selectWidth
                        });
                        ngModel.$render = function() {
                            element.select2('val', ngModel.$viewValue);
                            element.val(ngModel.$viewValue);
                        };
                    });
                    element.on('change', function() {
                        scope.$evalAsync(setModelValue);
                    });
                    scope.$watch('snChoices', function(newValue, oldValue) {
                        if (angular.isDefined(newValue) && newValue != oldValue) {
                            $timeout(function() {
                                setModelValue();
                            });
                        }
                    }, true);
    
                    function setModelValue() {
                        ngModel.$setViewValue(element.val());
                    };
                }
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/controls/directive.snTableReference.js */
    angular.module('sn.common.controls').directive('snTableReference', function($timeout) {
        "use strict";
        return {
            restrict: 'E',
            replace: true,
            scope: {
                field: "=",
                snChange: "&",
                snDisabled: "="
            },
            template: '<select ng-disabled="snDisabled" style="min-width: 150px;" name="{{field.name}}" ng-model="fieldValue" ng-model-options="{getterSetter: true}" ng-options="choice.value as choice.label for choice in field.choices"></select>',
            controller: function($scope) {
                $scope.fieldValue = function(selected) {
                    if (angular.isDefined(selected)) {
                        $scope.snChange({
                            newValue: selected
                        });
                    }
                    return $scope.field.value;
                }
            },
            link: function(scope, element) {
                var initTimeout = null;
                var fireReadyEvent = true;
                element.css("opacity", 0);
    
                function render() {
                    $timeout.cancel(initTimeout);
                    initTimeout = $timeout(function() {
                        element.css("opacity", 1);
                        element.select2("destroy");
                        element.select2();
                        if (fireReadyEvent) {
                            scope.$emit('select2.ready', element);
                            fireReadyEvent = false;
                        }
                    });
                }
                scope.$watch("field.displayValue", function(newValue, oldValue) {
                    if (newValue !== undefined && newValue != oldValue) {
                        render();
                    }
                });
                render();
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/controls/directive.snFieldReference.js */
    angular.module('sn.common.controls').directive('snFieldReference', function($timeout, $http, nowServer) {
        "use strict";
        return {
            restrict: 'E',
            replace: true,
            scope: {
                field: "=",
                snChange: "&",
                snDisabled: "=",
                getGlideForm: '&glideForm'
            },
            template: '<select ng-disabled="snDisabled" name="{{field.name}}" style="min-width: 150px;" ng-model="fieldValue" ng-model-options="{getterSetter: true}" ng-options="choice.name as choice.label for choice in field.choices"></select>',
            controller: function($scope) {
                $scope.fieldValue = function(selected) {
                    if (angular.isDefined(selected))
                        $scope.snChange({
                            newValue: selected
                        });
                    return $scope.field.value;
                }
                $scope.$watch('field.dependentValue', function(newVal, oldVal) {
                    if (!angular.isDefined(newVal))
                        return;
                    var src = nowServer.getURL('table_fields', 'exclude_formatters=true&fd_table=' + newVal);
                    $http.post(src).success(function(response) {
                        $scope.field.choices = response;
                        $scope.render();
                    });
                });
            },
            link: function(scope, element) {
                var initTimeout = null;
                var fireReadyEvent = true;
                scope.render = function() {
                    $timeout.cancel(initTimeout);
                    initTimeout = $timeout(function() {
                        element.select2("destroy");
                        element.select2();
                        if (fireReadyEvent) {
                            scope.$emit('select2.ready', element);
                            fireReadyEvent = false;
                        }
                    });
                };
                scope.$watch("field.displayValue", function(newValue, oldValue) {
                    if (newValue !== undefined && newValue != oldValue) {
                        scope.render();
                    }
                });
                scope.render();
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/controls/directive.snSyncWith.js */
    angular.module("sn.common.controls").directive('snSyncWith', function() {
        return {
            restrict: 'A',
            require: 'ngModel',
            scope: false,
            link: function(scope, elem, attr) {
                scope.journalField = scope.$eval(attr.snSyncWith);
                scope.value = scope.$eval(attr.ngModel);
                if (attr.snSyncWithValueInFn)
                    scope.$eval(attr.ngModel + "=" + attr.snSyncWithValueInFn, {
                        text: scope.value
                    });
                scope.$watch(function() {
                    return scope.$eval(attr.snSyncWith);
                }, function(nv, ov) {
                    if (nv !== ov)
                        scope.journalField = nv;
                });
                scope.$watch(function() {
                    return scope.$eval(attr.ngModel);
                }, function(nv, ov) {
                    if (nv !== ov)
                        scope.value = nv;
                });
                if (!window.g_form)
                    return;
                scope.$watch('value', function(n, o) {
                    if (n !== o)
                        setFieldValue();
                });
    
                function setFieldValue() {
                    setValue(scope.journalField, scope.value);
                }
    
                function setValue(field, value) {
                    value = !!value ? value : '';
                    var control = g_form.getControl(field);
                    if (attr.snSyncWithValueOutFn)
                        value = scope.$eval(attr.snSyncWithValueOutFn, {
                            text: value
                        })
                    control.value = value;
                    onChange(control.id);
                }
                scope.$watch('journalField', function(newValue, oldValue) {
                    if (newValue !== oldValue) {
                        if (oldValue)
                            setValue(oldValue, '');
                        if (newValue)
                            setFieldValue();
                    }
                }, true);
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/controls/directive.contenteditable.js */
    angular.module('sn.common.controls').directive('contenteditable', function($timeout) {
        return {
            require: 'ngModel',
            link: function(scope, elem, attrs, ctrl) {
                var changehandler = scope.changehandler;
                scope.usenewline = scope.usenewline + "" != "false";
                var newLine = "\n";
                var nodeBR = "BR";
                var nodeDIV = "DIV";
                var nodeText = "#text";
                var nbspRegExp = new RegExp(String.fromCharCode(160), "g");
                if (!scope.usenewline)
                    elem.keypress(function(event) {
                        if (event.which == "13") {
                            if (scope.entercallback)
                                scope.entercallback(elem);
                            event.preventDefault();
                        }
                    });
    
                function processNodes(nodes) {
                    var val = "";
                    for (var i = 0; i < nodes.length; i++) {
                        var node = nodes[i];
                        var follow = true;
                        switch (node.nodeName) {
                            case nodeText:
                                val += node.nodeValue.replace(nbspRegExp, " ");
                                break;
                            case nodeDIV:
                                val += newLine;
                                if (node.childNodes.length == 1 && node.childNodes[0].nodeName == nodeBR)
                                    follow = false;
                                break;
                            case nodeBR:
                                val += scope.usenewline ? newLine : "";
                        }
                        if (follow)
                            val += processNodes(node.childNodes)
                    }
                    return val;
                }
    
                function transferHTML() {
                    var val = processNodes(elem[0].childNodes);
                    ctrl.$setViewValue(val);
                }
    
                function transferText() {
                    var val = ctrl.$viewValue;
                    if (!val || val === null)
                        val = "";
                    val = val.replace(/\n/gi, scope.usenewline ? "<br/>" : "");
                    val = val.replace(/  /gi, " &nbsp;");
                    elem.html(val);
                }
    
                function processPlaceholder() {
                    if (elem[0].dataset) {
                        if (elem[0].textContent)
                            elem[0].dataset.divPlaceholderContent = 'true';
                        else if (elem[0].dataset.divPlaceholderContent)
                            delete(elem[0].dataset.divPlaceholderContent);
                    }
                }
                elem.bind('keyup', function() {
                    scope.$apply(function() {
                        transferHTML();
                        processPlaceholder();
                    });
                });
    
                function selectText(elem) {
                    var range;
                    var selection;
                    if (document.body.createTextRange) {
                        range = document.body.createTextRange();
                        range.moveToElementText(elem);
                        range.select();
                    } else if (window.getSelection) {
                        selection = window.getSelection();
                        range = document.createRange();
                        range.selectNodeContents(elem);
                        selection.removeAllRanges();
                        selection.addRange(range);
                    }
                }
                elem.bind('focus', function() {
                    if (scope[attrs.tracker] && scope[attrs.tracker]['isDefault_' + attrs.trackeratt])
                        $timeout(function() {
                            selectText(elem[0]);
                        });
                    elem.original = ctrl.$viewValue;
                });
                elem.bind('blur', function() {
                    scope.$apply(function() {
                        transferHTML();
                        processPlaceholder();
                        if (elem.original != ctrl.$viewValue && changehandler) {
                            if (scope[attrs.tracker] && typeof scope[attrs.tracker]['isDefault_' + attrs.trackeratt] != "undefined")
                                scope[attrs.tracker]['isDefault_' + attrs.trackeratt] = false;
                            changehandler(scope[attrs.tracker], attrs.trackeratt);
                        }
                    });
                });
                elem.bind('paste', function() {
                    scope.$apply(function() {
                        setTimeout(function() {
                            transferHTML();
                            transferText();
                        }, 0);
                        return false;
                    });
                });
                ctrl.$render = function() {
                    transferText();
                };
                scope.$watch('field.readonly', function() {
                    elem[0].contentEditable = !scope.$eval('field.readonly');
                });
                scope.$watch(
                    function() {
                        return {
                            val: elem[0].textContent
                        };
                    },
                    function(newValue, oldValue) {
                        if (newValue.val != oldValue.val)
                            processPlaceholder();
                    },
                    true);
                transferText();
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/controls/directive.snGlyph.js */
    angular.module("sn.common.controls").directive("snGlyph", function() {
        "use strict";
        return {
            restrict: 'E',
            replace: true,
            scope: {
                char: "@",
            },
            template: '<span class="glyphicon glyphicon-{{char}}" />',
            link: function(scope) {}
        }
    });
    angular.module("sn.common.controls").directive('fa', function() {
            return {
                restrict: 'E',
                template: '<span class="fa" aria-hidden="true"></span>',
                replace: true,
                link: function(scope, element, attrs) {
                    'use strict';
                    var currentClasses = {};
    
                    function _observeStringAttr(attr, baseClass) {
                        var className;
                        attrs.$observe(attr, function() {
                            baseClass = baseClass || 'fa-' + attr;
                            element.removeClass(currentClasses[attr]);
                            if (attrs[attr]) {
                                className = [baseClass, attrs[attr]].join('-');
                                element.addClass(className);
                                currentClasses[attr] = className;
                            }
                        });
                    }
                    _observeStringAttr('name', 'fa');
                    _observeStringAttr('rotate');
                    _observeStringAttr('flip');
                    _observeStringAttr('stack');
                    attrs.$observe('size', function() {
                        var className;
                        element.removeClass(currentClasses.size);
                        if (attrs.size === 'large') {
                            className = 'fa-lg';
                        } else if (!isNaN(parseInt(attrs.size, 10))) {
                            className = 'fa-' + attrs.size + 'x';
                        }
                        element.addClass(className);
                        currentClasses.size = className;
                    });
                    attrs.$observe('stack', function() {
                        var className;
                        element.removeClass(currentClasses.stack);
                        if (attrs.stack === 'large') {
                            className = 'fa-stack-lg';
                        } else if (!isNaN(parseInt(attrs.stack, 10))) {
                            className = 'fa-stack-' + attrs.stack + 'x';
                        }
                        element.addClass(className);
                        currentClasses.stack = className;
                    });
    
                    function _observeBooleanAttr(attr, className) {
                        var value;
                        attrs.$observe(attr, function() {
                            className = className || 'fa-' + attr;
                            value = attr in attrs && attrs[attr] !== 'false' && attrs[attr] !== false;
                            element.toggleClass(className, value);
                        });
                    }
                    _observeBooleanAttr('border');
                    _observeBooleanAttr('fw');
                    _observeBooleanAttr('inverse');
                    _observeBooleanAttr('spin');
                    element.toggleClass('fa-li',
                        element.parent() &&
                        element.parent().prop('tagName') === 'LI' &&
                        element.parent().parent() &&
                        element.parent().parent().hasClass('fa-ul') &&
                        element.parent().children()[0] === element[0] &&
                        attrs.list !== 'false' &&
                        attrs.list !== false
                    );
                    attrs.$observe('alt', function() {
                        var altText = attrs.alt,
                            altElem = element.next(),
                            altElemClass = 'fa-alt-text';
                        if (altText) {
                            element.removeAttr('alt');
                            if (!altElem || !altElem.hasClass(altElemClass)) {
                                element.after('<span class="sr-only fa-alt-text"></span>');
                                altElem = element.next();
                            }
                            altElem.text(altText);
                        } else if (altElem && altElem.hasClass(altElemClass)) {
                            altElem.remove();
                        }
                    });
                }
            };
        })
        .directive('faStack', function() {
            return {
                restrict: 'E',
                transclude: true,
                template: '<span ng-transclude class="fa-stack fa-lg"></span>',
                replace: true,
                link: function(scope, element, attrs) {
                    var currentClasses = {};
    
                    function _observeStringAttr(attr, baseClass) {
                        var className;
                        attrs.$observe(attr, function() {
                            baseClass = baseClass || 'fa-' + attr;
                            element.removeClass(currentClasses[attr]);
                            if (attrs[attr]) {
                                className = [baseClass, attrs[attr]].join('-');
                                element.addClass(className);
                                currentClasses[attr] = className;
                            }
                        });
                    }
                    _observeStringAttr('size');
                    attrs.$observe('size', function() {
                        var className;
                        element.removeClass(currentClasses.size);
                        if (attrs.size === 'large') {
                            className = 'fa-lg';
                        } else if (!isNaN(parseInt(attrs.size, 10))) {
                            className = 'fa-' + attrs.size + 'x';
                        }
                        element.addClass(className);
                        currentClasses.size = className;
                    });
                }
            };
        });;
    /*! RESOURCE: /scripts/sn/common/controls/directive.snImageUploader.js */
    angular.module('sn.common.controls').directive('snImageUploader', function($window, $rootScope, $timeout, getTemplateUrl, i18n, snAttachmentHandler) {
        var DRAG_IMAGE_SELECT = i18n.getMessage('Drag image or click to select');
        return {
            restrict: 'E',
            replace: true,
            templateUrl: getTemplateUrl('directive.snImageUploader'),
            transclude: true,
            scope: {
                readOnly: '@',
                tableName: '@',
                sysId: '@',
                fieldName: '@',
                onUpload: '&',
                onDelete: '&',
                uploadMessage: '@',
                src: '='
            },
            controller: function($scope) {
                $scope.uploading = false;
                $scope.getTitle = function() {
                    if ($scope.readOnly !== 'true')
                        return DRAG_IMAGE_SELECT;
                    return '';
                }
            },
            link: function(scope, element) {
                function isValidImage(file) {
                    if (file.type.indexOf('image') != 0) {
                        $alert(i18n.getMessage('Please select an image'));
                        return false;
                    }
                    if (file.type.indexOf('tiff') > 0) {
                        $alert(i18n.getMessage('Please select a common image format such as gif, jpeg or png'));
                        return false;
                    }
                    return true;
                }
    
                function $alert(message) {
                    alert(message);
                }
                scope.onFileSelect = function($files) {
                    if (scope.readOnly === 'true')
                        return;
                    if ($files.length == 0)
                        return;
                    var file = $files[0];
                    if (!isValidImage(file))
                        return;
                    var uploadParams = {
                        sysparm_fieldname: scope.fieldName
                    };
                    scope.uploading = true;
                    snAttachmentHandler.create(scope.tableName, scope.sysId).uploadAttachment(file, uploadParams).then(function(response) {
                        $timeout(function() {
                            scope.uploading = false;
                        });
                        if (scope.onUpload)
                            scope.onUpload({
                                thumbnail: response.thumbnail
                            });
                        $rootScope.$broadcast("snImageUploader:complete", scope.sysId, response);
                    });
                }
                scope.openFileSelector = function($event) {
                    $event.stopPropagation();
                    var input = element.find('input[type=file]');
                    input.click();
                }
                scope.activateUpload = function($event) {
                    if (scope.readOnly !== 'true')
                        scope.openFileSelector($event);
                    else
                        scope.showUpload = !scope.showUpload;
                }
                scope.deleteAttachment = function() {
                    var sys_id = scope.src.split(".")[0];
                    snAttachmentHandler.deleteAttachment(sys_id).then(function() {
                        scope.src = null;
                        if (scope.onDelete)
                            scope.onDelete();
                        $rootScope.$broadcast("snImageUploader:delete", scope.sysId, sys_id);
                    });
                }
            }
        }
    });;;
    /*! RESOURCE: /scripts/sn/common/i18n/js_includes_i18n.js */
    /*! RESOURCE: /scripts/sn/common/i18n/_module.js */
    angular.module('sn.common.i18n', ['sn.common.glide']);
    angular.module('sn.i18n', ['sn.common.i18n']);;
    /*! RESOURCE: /scripts/sn/common/i18n/directive.snBindI18n.js */
    angular.module('sn.common.i18n').directive('snBindI18n', function(i18n, $sanitize) {
        return {
            restrict: 'A',
            link: function(scope, iElem, iAttrs) {
                i18n.getMessage(iAttrs.snBindI18n, function(translatedValue) {
                    var sanitizedValue = $sanitize(translatedValue);
                    iElem.append(sanitizedValue);
                });
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/i18n/directive.message.js */
    angular.module('sn.common.i18n').directive('nowMessage', function(i18n) {
        return {
            restrict: 'E',
            priority: 0,
            template: '',
            replace: true,
            compile: function(element, attrs, transclude) {
                var value = element.attr('value');
                if (!attrs.key || !value)
                    return;
                i18n.loadMessage(attrs.key, value);
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/i18n/service.i18n.js */
    angular.module('sn.common.i18n').factory('i18n', function(nowServer, $http, $window, $log) {
        var messageMap = {};
        var isDebug = $window.NOW ? $window.NOW.i18n_debug : true;
    
        function getMessageFromServer(msgKey, callback) {
            getMessagesFromServer([msgKey], function() {
                if (callback)
                    callback(messageMap[msgKey]);
            });
        }
    
        function getMessagesFromServer(msgArray, callback, msgArrayFull) {
            var url = nowServer.getURL('message');
            $http.post(url, {
                messages: msgArray
            }).success(function(response) {
                var messages = response.messages;
                for (var i in messages) {
                    loadMessage(i, messages[i]);
                }
                var returnMessages = {},
                    allMessages = msgArrayFull || msgArray;
                for (var j = 0; j < allMessages.length; j++) {
                    var key = allMessages[j];
                    returnMessages[key] = messageMap[key];
                }
                if (callback)
                    callback(returnMessages);
            });
        }
    
        function loadMessage(msgKey, msgValue) {
            messageMap[msgKey] = msgValue;
        }
    
        function debug(msg) {
            if (!isDebug)
                return;
            $log.log('i18n: ' + msg);
        }
    
        function interpolate(param) {
            return this.replace(/{([^{}]*)}/g,
                function(a, b) {
                    var r = param[b];
                    return typeof r === 'string' || typeof r === 'number' ? r : a;
                }
            );
        }
        if (!String.prototype.withValues)
            String.prototype.withValues = interpolate;
        return {
            getMessage: function(msgKey, callback) {
                debug('getMessage: Checking for ' + msgKey);
                if (messageMap.hasOwnProperty(msgKey)) {
                    var message = messageMap[msgKey];
                    if (typeof(callback) == 'function')
                        callback(message);
                    debug('getMessage: Found: ' + msgKey + ', message: ' + message);
                    return message;
                }
                debug('getMessage: Not found: ' + msgKey + ', querying server');
                getMessageFromServer(msgKey, callback);
                msgKey.withValues = interpolate;
                if (typeof(callback) != 'function')
                    $log.warn('getMessage (key="' + msgKey + '"): synchronous use not supported in Mobile or Service Portal unless message is already cached');
                return msgKey;
            },
            format: function(message) {
                if (arguments.length == 1)
                    return message;
                if (arguments.length == 2 && (typeof arguments[1] === 'object'))
                    return interpolate.call(message, arguments[1]);
                return interpolate.call(message, [].slice.call(arguments, 1));
            },
            getMessages: function(msgArray, callback) {
                debug('getMessages: Checking for ' + msgArray.join(','));
                var results = {},
                    needMessage = [],
                    needServerRequest = false;
                for (var i = 0; i < msgArray.length; i++) {
                    var key = msgArray[i];
                    if (!messageMap.hasOwnProperty(key)) {
                        debug('getMessages: Did not find ' + key);
                        needMessage.push(key);
                        needServerRequest = true;
                        results[key] = key;
                        continue;
                    }
                    results[key] = messageMap[key];
                    debug('getMessages: Found ' + key + ', message: ' + results[key]);
                }
                if (needServerRequest) {
                    debug('getMessages: Querying server for ' + needMessage.join(','));
                    getMessagesFromServer(needMessage, callback, msgArray);
                } else if (typeof(callback) == 'function') {
                    debug('getMessages: Found all messages');
                    callback(results);
                }
                return results;
            },
            clearMessages: function() {
                debug('clearMessages: clearing messages');
                messageMap = {};
            },
            loadMessage: function(msgKey, msgValue) {
                loadMessage(msgKey, msgValue);
                debug('loadMessage: loaded key: ' + msgKey + ', value: ' + msgValue);
            },
            preloadMessages: function() {
                var that = this
                angular.element('now-message').each(function() {
                    var elem = angular.element(this);
                    that.loadMessage(elem.attr('key'), elem.attr('value'));
                })
            }
        };
    });;;
    /*! RESOURCE: /scripts/sn/common/link/js_includes_link.js */
    /*! RESOURCE: /scripts/sn/common/link/_module.js */
    angular.module("sn.common.link", []);;
    /*! RESOURCE: /scripts/sn/common/link/directive.snLinkContent.js */
    angular.module('sn.common.link').directive('snLinkContent', function($compile, linkContentTypes) {
        'use strict';
        return {
            restrict: 'E',
            replace: true,
            template: "<span />",
            scope: {
                link: "="
            },
            link: function(scope, elem) {
                var linkDirective = linkContentTypes.forType(scope.link);
                elem.attr(linkDirective, "");
                $compile(elem)(scope);
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/link/directive.snLinkContentYoutube.js */
    angular.module('sn.common.link').directive('snLinkContentYoutube', function(getTemplateUrl, $sce, inFrameSet) {
        'use strict';
        return {
            restrict: 'A',
            replace: true,
            templateUrl: getTemplateUrl('snLinkContentYoutube.xml'),
            scope: {
                link: "="
            },
            controller: function($scope) {
                $scope.playerActive = false;
                $scope.width = (inFrameSet) ? '248px' : '500px';
                $scope.height = (inFrameSet) ? '139px' : '281px';
                $scope.showPlayer = function() {
                    $scope.playerActive = true;
                };
                $scope.getVideoEmbedLink = function() {
                    if ($scope.link.embedLink) {
                        var videoLink = $scope.link.embedLink + "?autoplay=1";
                        return $sce.trustAsHtml("<iframe width='" + $scope.width + "' height='" + $scope.height + "' autoplay='1' frameborder='0' allowfullscreen='' src='" + videoLink + "'></iframe>");
                    }
                };
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/link/directive.snLinkContentSoundcloud.js */
    angular.module('sn.common.link').directive('snLinkContentSoundcloud', function(getTemplateUrl, $sce, inFrameSet) {
        'use strict';
        return {
            restrict: 'A',
            replace: true,
            templateUrl: getTemplateUrl('snLinkContentSoundcloud.xml'),
            scope: {
                link: "="
            },
            controller: function($scope) {
                $scope.playerActive = false;
                $scope.width = (inFrameSet) ? '248px' : '500px';
                $scope.height = (inFrameSet) ? '139px' : '281px';
                $scope.showPlayer = function() {
                    $scope.playerActive = true;
                };
                $scope.getVideoEmbedLink = function() {
                    if ($scope.link.embedLink) {
                        var videoLink = $scope.link.embedLink + "&amp;auto_play=true";
                        var width = (inFrameSet) ? 248 : 500;
                        return $sce.trustAsHtml("<iframe width='" + $scope.width + "' height='" + $scope.height + "' autoplay='1' frameborder='0' allowfullscreen='' src='" + videoLink + "'></iframe>");
                    }
                };
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/link/directive.snLinkContentArticle.js */
    angular.module('sn.common.link').directive('snLinkContentArticle', function(getTemplateUrl) {
        'use strict';
        return {
            restrict: 'A',
            replace: true,
            templateUrl: getTemplateUrl('snLinkContentArticle.xml'),
            scope: {
                link: "="
            },
            controller: function($scope) {
                $scope.backgroundImageStyle = $scope.link.imageLink ?
                    {
                        "background-image": 'url(' + $scope.link.imageLink + ')'
                    } :
                    {};
                $scope.isVisible = function() {
                    var link = $scope.link;
                    return !!link.shortDescription || !!link.imageLink;
                };
                $scope.hasDescription = function() {
                    var link = $scope.link;
                    return link.shortDescription && (link.shortDescription !== link.title);
                };
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/link/directive.snLinkContentError.js */
    angular.module('sn.common.link').directive('snLinkContentError', function(getTemplateUrl) {
        'use strict';
        return {
            restrict: 'A',
            replace: true,
            templateUrl: getTemplateUrl('snLinkContentError.xml'),
            scope: {
                link: "="
            },
            controller: function($scope) {}
        }
    });;
    /*! RESOURCE: /scripts/sn/common/link/directive.snLinkContentImage.js */
    angular.module('sn.common.link').directive('snLinkContentImage', function(getTemplateUrl) {
        'use strict';
        return {
            restrict: 'A',
            replace: true,
            templateUrl: getTemplateUrl('snLinkContentImage.xml'),
            scope: {
                link: "="
            },
            controller: function($scope) {}
        }
    });;
    /*! RESOURCE: /scripts/sn/common/link/directive.snLinkContentAttachment.js */
    angular.module('sn.common.link').directive('snLinkContentAttachment', function(getTemplateUrl) {
        'use strict';
        return {
            restrict: 'EA',
            replace: true,
            templateUrl: getTemplateUrl('snLinkContentAttachment.xml'),
            scope: {
                attachment: '=',
                link: '='
            },
            controller: function($scope, $element, snCustomEvent) {
                $scope.attachment = $scope.attachment || $scope.link.attachment;
                $scope.calcImageSize = function() {
                    var imageWidth = $scope.width;
                    var imageHeight = $scope.height;
                    var MAX_IMAGE_SIZE = $element.width() < 298 ? $element.width() : 298;
                    if (imageHeight < 0 || imageWidth < 0)
                        return "";
                    if (imageHeight > imageWidth) {
                        if (imageHeight >= MAX_IMAGE_SIZE) {
                            imageWidth *= MAX_IMAGE_SIZE / imageHeight;
                            imageHeight = MAX_IMAGE_SIZE;
                        }
                    } else {
                        if (imageWidth >= MAX_IMAGE_SIZE) {
                            imageHeight *= MAX_IMAGE_SIZE / imageWidth;
                            imageWidth = MAX_IMAGE_SIZE
                        }
                    }
                    return "height: " + imageHeight + "px; width: " + imageWidth + "px;";
                };
                $scope.aspectRatioClass = function() {
                    return ($scope.height > $scope.width) ? 'limit-height' : 'limit-width';
                };
                $scope.showImage = function(event) {
                    if (event.keyCode === 9)
                        return;
                    snCustomEvent.fire('sn.attachment.preview', event, $scope.attachment.rawData);
                };
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/link/directive.snLinkContentRecord.js */
    angular.module('sn.common.link').directive('snLinkContentRecord', function(getTemplateUrl) {
        'use strict';
        return {
            restrict: 'A',
            replace: true,
            templateUrl: getTemplateUrl('snLinkContentRecord.xml'),
            scope: {
                link: '='
            },
            controller: function($scope) {
                $scope.isTitleVisible = function() {
                    return !$scope.isDescriptionVisible() && $scope.link.title;
                };
                $scope.isDescriptionVisible = function() {
                    return $scope.link.shortDescription;
                };
                $scope.hasNoHeader = function() {
                    return !$scope.isTitleVisible() && !$scope.isDescriptionVisible();
                };
                $scope.isUnassigned = function() {
                    return $scope.link.isTask && !$scope.link.avatarID;
                };
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/link/provider.linkContentTypes.js */
    angular.module('sn.common.link').provider('linkContentTypes', function linkContentTypesProvider() {
        "use strict";
        var linkDirectiveMap = {
            'record': "sn-link-content-record",
            'video': "sn-link-content-youtube",
            'music.song': "sn-link-content-soundcloud",
            'link': 'sn-link-content-article',
            'article': 'sn-link-content-article',
            'website': 'sn-link-content-article',
            'image': 'sn-link-content-image'
        };
        this.$get = function linkContentTypesFactory() {
            return {
                forType: function(link) {
                    if (link.isUnauthorized)
                        return "sn-link-content-error";
                    if (!link.isActive)
                        return "no-card";
                    if (link.attachment)
                        return "sn-link-content-attachment";
                    return linkDirectiveMap[link.type] || "no-card";
                }
            }
        };
    });;;
    /*! RESOURCE: /scripts/sn/common/mention/js_includes_mention.js */
    /*! RESOURCE: /scripts/sn/common/mention/_module.js */
    angular.module("sn.common.mention", []);;
    /*! RESOURCE: /scripts/sn/common/mention/directive.snMentionPopover.js */
    angular.module('sn.common.mention').directive("snMentionPopover", function(getTemplateUrl, $timeout) {
        'use strict';
        return {
            restrict: 'E',
            replace: true,
            templateUrl: getTemplateUrl('snMentionPopover.xml'),
            link: function(scope, elem, $attrs) {
                elem.detach().appendTo(document.body);
                scope.profile = scope.$eval($attrs.profile);
                scope.dontPositionManually = scope.$eval($attrs.dontpositionmanually) || false;
                scope.onClick = function(event) {
                    if (!angular.element(event.target).closest("#mention-popover").length ||
                        angular.element(event.target).closest("#direct-message-popover-trigger").length) {
                        scope.$evalAsync(function() {
                            scope.$parent.showPopover = false;
                            if (scope.dontPositionManually && !(scope.$eval($attrs.snavatarpopover))) {
                                elem.remove();
                            } else {
                                scope.$broadcast("sn-avatar-popover-destroy");
                            }
                        });
                    }
                };
                scope.clickListener = $timeout(function() {
                    angular.element('html').on('click.mentionPopover', scope.onClick);
                });
    
                function setPopoverPosition(clickX, clickY) {
                    var topPosition;
                    var leftPosition;
                    var windowHeight = window.innerHeight;
                    var windowWidth = window.innerWidth;
                    if (((clickY - (elem.height() / 2))) < 10)
                        topPosition = 10;
                    else
                        topPosition = ((clickY + (elem.height() / 2)) > windowHeight) ? windowHeight - elem.height() - 15 : clickY - (elem.height() / 2);
                    leftPosition = ((clickX + 20 + (elem.width())) > windowWidth) ? windowWidth - elem.width() - 15 : clickX + 20;
                    elem.css("top", topPosition + "px").css("left", leftPosition + "px");
                }
                if (!scope.dontPositionManually) {
                    $timeout(function() {
                        var clickX = (scope.$parent && scope.$parent.clickEvent && scope.$parent.clickEvent.pageX) ? scope.$parent.clickEvent.pageX : clickX || 300;
                        var clickY = (scope.$parent && scope.$parent.clickEvent && scope.$parent.clickEvent.pageY) ? scope.$parent.clickEvent.pageY : clickY || 300;
                        setPopoverPosition(clickX, clickY);
                        elem.velocity({
                            opacity: 1
                        }, {
                            duration: 100,
                            easing: "cubic"
                        });
                    });
                }
            },
            controller: function($scope, $element) {
                $scope.$on("$destroy", function() {
                    angular.element('html').off('click.mentionPopover', $scope.onClick);
                    $element.remove();
                });
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/mention/service.snMention.js */
    angular.module("sn.common.mention").factory("snMention", function(liveProfileID, $q, $http) {
        "use strict";
        var MENTION_PATH = "/api/now/form/mention/record";
        var USER_PATH = '/api/now/ui/user/';
        var avatarCache = {};
    
        function retrieveMembers(table, document, term) {
            if (!term || !document || !table) {
                var deferred = $q.defer();
                deferred.resolve([]);
                return deferred.promise;
            }
            return $http({
                url: MENTION_PATH + "/" + table + "/" + document,
                method: "GET",
                params: {
                    term: term
                }
            }).then(function(response) {
                var members = response.data.result;
                var promises = [];
                angular.forEach(members, function(user) {
                    if (avatarCache[user.sys_id]) {
                        user.initials = avatarCache[user.sys_id].initials;
                        user.avatar = avatarCache[user.sys_id].avatar;
                    } else {
                        var promise = $http.get(USER_PATH + user.sys_id).success(function(response) {
                            user.initials = response.result.user_initials;
                            user.avatar = response.result.user_avatar;
                            avatarCache[user.sys_id] = {
                                initials: user.initials,
                                avatar: user.avatar
                            };
                        });
                        promises.push(promise);
                    }
                });
                return $q.all(promises).then(function() {
                    return members;
                });
            })
        }
        return {
            retrieveMembers: retrieveMembers
        }
    });;;
    /*! RESOURCE: /scripts/sn/common/messaging/js_includes_messaging.js */
    /*! RESOURCE: /scripts/sn/common/messaging/_module.js */
    angular.module('sn.common.messaging', []);
    angular.module('sn.messaging', ['sn.common.messaging']);;
    /*! RESOURCE: /scripts/doctype/CustomEventManager.js */
    var NOW = NOW || {};
    var CustomEventManager = (function(existingCustomEvent) {
        "use strict";
        var events = (existingCustomEvent && existingCustomEvent.events) || {};
        var isFiringFlag = false;
        var trace = false;
        var suppressEvents = false;
        var NOW_MSG = 'NOW.PostMessage';
    
        function observe(eventName, fn) {
            if (trace)
                jslog("$CustomEventManager observing: " + eventName);
            on(eventName, fn);
        }
    
        function on(name, func) {
            if (!func || typeof func !== 'function')
                return;
            if (typeof name === 'undefined')
                return;
            if (!events[name])
                events[name] = [];
            events[name].push(func);
        }
    
        function un(name, func) {
            if (!events[name])
                return;
            var idx = -1;
            for (var i = 0; i < events[name].length; i++) {
                if (events[name][i] === func) {
                    idx = i;
                    break;
                }
            }
            if (idx >= 0)
                events[name].splice(idx, 1)
        }
    
        function unAll(name) {
            if (events[name])
                delete events[name];
        }
    
        function fire(eventName, args) {
            if (trace)
                jslog("$CustomEventManager firing: " + eventName + " args: " + arguments.length);
            return fireEvent.apply(null, arguments);
        }
    
        function fireUp(eventName, args) {
            var win = window;
            while (win) {
                try {
                    if (win.CustomEvent.fireEvent.apply(null, arguments) === false)
                        return;
                    win = win.parent === win ? null : win.parent;
                } catch (e) {
                    return;
                }
            }
        }
    
        function fireEvent() {
            if (suppressEvents)
                return true;
            var args = Array.prototype.slice.apply(arguments);
            var name = args.shift();
            var eventList = events[name];
            if (!eventList)
                return true;
            var event = eventList.slice();
            isFiringFlag = true;
            for (var i = 0, l = event.length; i < l; i++) {
                var ev = event[i];
                if (!ev)
                    continue;
                if (ev.apply(null, args) === false) {
                    isFiringFlag = false;
                    return false;
                }
            }
            isFiringFlag = false;
            return true;
        }
    
        function isFiring() {
            return isFiringFlag;
        }
    
        function forward(name, element, func) {
            on(name, func);
            element.addEventListener(name, function(e) {
                fireEvent(e.type, this, e);
            }.bind(api));
        }
    
        function registerPostMessageEvent() {
            if (NOW.registeredPostMessageEvent) {
                return;
            }
            if (!window.postMessage) {
                return;
            }
            window.addEventListener('message', function(event) {
                var nowMessageJSON = event.data;
                var nowMessage;
                try {
                    nowMessage = JSON.parse(nowMessageJSON.toString());
                } catch (e) {
                    return;
                }
                if (!nowMessage.type == NOW_MSG) {
                    return;
                }
                fire(nowMessage.eventName, nowMessage.args);
            }, false);
            NOW.registeredPostMessageEvent = true;
        }
    
        function doPostMessage(win, event, msg, targetOrigin) {
            var nowMessage = {
                type: NOW_MSG,
                eventName: event,
                args: msg
            };
            var nowMessageJSON;
            if (!win || !win.postMessage) {
                return
            }
            nowMessageJSON = JSON.stringify(nowMessage);
            win.postMessage(nowMessageJSON, targetOrigin);
        }
    
        function fireTop(eventName, args) {
            if (trace)
                jslog("$CustomEventManager firing: " + eventName + " args: " + arguments.length);
            fireEvent.apply(null, arguments);
            var t = getTopWindow();
            if (t !== null && window !== t)
                t.CustomEvent.fire(eventName, args);
        }
    
        function fireAll(eventName, args) {
            if (trace)
                jslog("$CustomEventManager firing: " + eventName + " args: " + arguments.length);
            var topWindow = getTopWindow();
            notifyAllFrom(topWindow);
    
            function notifyAllFrom(rootFrame) {
                var childFrame;
                rootFrame.CustomEvent.fireEvent(eventName, args);
                for (var i = 0; i < rootFrame.length; i++) {
                    try {
                        childFrame = rootFrame[i];
                        if (!childFrame)
                            continue;
                        if (childFrame.CustomEvent && typeof childFrame.CustomEvent.fireEvent === "function") {
                            notifyAllFrom(childFrame);
                        }
                    } catch (e) {}
                }
            }
        }
    
        function fireToWindow(targetWindow, eventName, args, usePostMessage, targetOrigin) {
            if (trace)
                jslog("$CustomEventManager firing: " + eventName + " args: " + args.length);
            if (usePostMessage) {
                doPostMessage(targetWindow, eventName, args, targetOrigin);
            } else {
                targetWindow.CustomEvent.fireEvent(eventName, args);
            }
        }
    
        function getTopWindow() {
            var topWindow = window.self;
            try {
                while (topWindow.CustomEvent.fireEvent && topWindow !== topWindow.parent && topWindow.parent.CustomEvent.fireEvent) {
                    topWindow = topWindow.parent;
                }
            } catch (e) {}
            return topWindow;
        }
    
        function isTopWindow() {
            return getTopWindow() == window.self;
        }
    
        function jslog(msg, src, dateTime) {
            try {
                if (!src) {
                    var path = window.self.location.pathname;
                    src = path.substring(path.lastIndexOf('/') + 1);
                }
                if (window.self.opener && window != window.self.opener) {
                    if (window.self.opener.jslog) {
                        window.self.opener.jslog(msg, src, dateTime);
                    }
                } else if (parent && parent.jslog && jslog != parent.jslog) {
                    parent.jslog(msg, src, dateTime);
                } else {
                    if (window.console && window.console.log)
                        console.log(msg);
                }
            } catch (e) {}
        }
        var api = {
            set trace(value) {
                trace = !!value;
            },
            get trace() {
                return trace;
            },
            set suppressEvents(value) {
                suppressEvents = !!value;
            },
            get suppressEvents() {
                return suppressEvents;
            },
            get events() {
                return events;
            },
            on: on,
            un: un,
            unAll: unAll,
            forward: forward,
            isFiring: isFiring,
            fireEvent: fireEvent,
            observe: observe,
            fire: fire,
            fireTop: fireTop,
            fireAll: fireAll,
            fireToWindow: fireToWindow,
            isTopWindow: isTopWindow,
            fireUp: fireUp,
            toString: function() {
                return 'CustomEventManager';
            }
        };
        registerPostMessageEvent();
        return api;
    })(NOW.CustomEvent);
    NOW.CustomEvent = CustomEventManager;
    if (typeof CustomEvent !== "undefined") {
        CustomEvent.observe = NOW.CustomEvent.observe.bind(NOW.CustomEvent);
        CustomEvent.fire = NOW.CustomEvent.fire.bind(NOW.CustomEvent);
        CustomEvent.fireUp = NOW.CustomEvent.fireUp.bind(NOW.CustomEvent);
        CustomEvent.fireTop = NOW.CustomEvent.fireTop.bind(NOW.CustomEvent);
        CustomEvent.fireAll = NOW.CustomEvent.fireAll.bind(NOW.CustomEvent);
        CustomEvent.fireToWindow = NOW.CustomEvent.fireToWindow.bind(NOW.CustomEvent);
        CustomEvent.on = NOW.CustomEvent.on.bind(NOW.CustomEvent);
        CustomEvent.un = NOW.CustomEvent.un.bind(NOW.CustomEvent);
        CustomEvent.unAll = NOW.CustomEvent.unAll.bind(NOW.CustomEvent);
        CustomEvent.forward = NOW.CustomEvent.forward.bind(NOW.CustomEvent);
        CustomEvent.isFiring = NOW.CustomEvent.isFiring.bind(NOW.CustomEvent);
        CustomEvent.fireEvent = NOW.CustomEvent.fireEvent.bind(NOW.CustomEvent);
        CustomEvent.events = NOW.CustomEvent.events;
        CustomEvent.isTopWindow = NOW.CustomEvent.isTopWindow.bind(NOW.CustomEvent);
    } else {
        window.CustomEvent = NOW.CustomEvent;
    };
    /*! RESOURCE: /scripts/sn/common/messaging/service.snCustomEvent.js */
    angular.module('sn.common.messaging').factory('snCustomEvent', function() {
        "use strict";
        if (typeof NOW.CustomEvent === 'undefined')
            throw "CustomEvent not found in NOW global";
        return NOW.CustomEvent;
    });;;
    /*! RESOURCE: /scripts/sn/common/notification/js_includes_notification.js */
    /*! RESOURCE: /scripts/sn/common/notification/_module.js */
    angular.module('sn.common.notification', ['sn.common.util', 'ngSanitize']);;
    /*! RESOURCE: /scripts/sn/common/notification/factory.notificationWrapper.js */
    angular.module("sn.common.notification").factory("snNotificationWrapper", function($window, $timeout) {
        "use strict";
    
        function assignHandler(notification, handlerName, options) {
            if (typeof options[handlerName] === "function")
                notification[handlerName.toLowerCase()] = options[handlerName];
        }
        return function NotificationWrapper(title, options) {
            var defaults = {
                dir: 'auto',
                lang: 'en_US',
                decay: true,
                lifespan: 4000,
                body: "",
                tag: "",
                icon: '/native_notification_icon.png'
            };
            var optionsOnClick = options.onClick;
            options.onClick = function() {
                if (angular.isFunction($window.focus))
                    $window.focus();
                if (typeof optionsOnClick === "function")
                    optionsOnClick();
            }
            var result = {};
            options = angular.extend(defaults, options);
            var previousOnClose = options.onClose;
            options.onClose = function() {
                if (angular.isFunction(result.onclose))
                    result.onclose();
                if (angular.isFunction(previousOnClose))
                    previousOnClose();
            }
            var notification = new $window.Notification(title, options);
            assignHandler(notification, "onShow", options);
            assignHandler(notification, "onClick", options);
            assignHandler(notification, "onError", options);
            assignHandler(notification, "onClose", options);
            if (options.decay && options.lifespan > 0)
                $timeout(function() {
                    notification.close();
                }, options.lifespan)
            result.close = function() {
                notification.close();
            }
            return result;
        }
    });
    /*! RESOURCE: /scripts/sn/common/notification/service.snNotifier.js */
    angular.module("sn.common.notification").factory("snNotifier", function($window, snNotificationWrapper) {
        "use strict";
        return function(settings) {
            function requestNotificationPermission() {
                if ($window.Notification && $window.Notification.permission === "default")
                    $window.Notification.requestPermission();
            }
    
            function canUseNativeNotifications() {
                return ($window.Notification && $window.Notification.permission === "granted");
            }
            var currentNotifications = [];
            settings = angular.extend({
                notifyMethods: ["native", "glide"]
            }, settings);
            var methods = {
                'native': nativeNotify,
                'glide': glideNotify
            };
    
            function nativeNotify(title, options) {
                if (canUseNativeNotifications()) {
                    var newNotification = snNotificationWrapper(title, options);
                    newNotification.onclose = function() {
                        stopTrackingNotification(newNotification)
                    };
                    currentNotifications.push(newNotification);
                    return true;
                }
                return false;
            }
    
            function glideNotify(title, options) {
                return false;
            }
    
            function stopTrackingNotification(newNotification) {
                var index = currentNotifications.indexOf(newNotification);
                if (index > -1)
                    currentNotifications.splice(index, 1);
            }
    
            function notify(title, options) {
                if (typeof options === "string")
                    options = {
                        body: options
                    };
                options = options || {};
                for (var i = 0, len = settings.notifyMethods.length; i < len; i++)
                    if (typeof settings.notifyMethods[i] == "string") {
                        if (methods[settings.notifyMethods[i]](title, options))
                            break;
                    } else {
                        if (settings.notifyMethods[i](title, options))
                            break;
                    }
            }
    
            function clearAllNotifications() {
                while (currentNotifications.length > 0)
                    currentNotifications.pop().close();
            }
            return {
                notify: notify,
                canUseNativeNotifications: canUseNativeNotifications,
                clearAllNotifications: clearAllNotifications,
                requestNotificationPermission: requestNotificationPermission
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/notification/directive.snNotification.js */
    angular.module('sn.common.notification').directive('snNotification', function($timeout, $rootScope) {
        "use strict";
        return {
            restrict: 'E',
            replace: true,
            template: '<div class="notification-container"></div>',
            link: function(scope, element) {
                scope.addNotification = function(payload) {
                        if (!payload)
                            payload = {};
                        if (!payload.text)
                            payload.text = '';
                        if (!payload.classes)
                            payload.classes = '';
                        if (!payload.duration)
                            payload.duration = 5000;
                        angular.element('<div/>').qtip({
                            content: {
                                text: payload.text,
                                title: {
                                    button: false
                                }
                            },
                            position: {
                                target: [0, 0],
                                container: angular.element('.notification-container')
                            },
                            show: {
                                event: false,
                                ready: true,
                                effect: function() {
                                    angular.element(this).stop(0, 1).animate({
                                        height: 'toggle'
                                    }, 400, 'swing');
                                },
                                delay: 0,
                                persistent: false
                            },
                            hide: {
                                event: false,
                                effect: function(api) {
                                    angular.element(this).stop(0, 1).animate({
                                        height: 'toggle'
                                    }, 400, 'swing');
                                }
                            },
                            style: {
                                classes: 'jgrowl' + ' ' + payload.classes,
                                tip: false
                            },
                            events: {
                                render: function(event, api) {
                                    if (!api.options.show.persistent) {
                                        angular.element(this).bind('mouseover mouseout', function(e) {
                                                clearTimeout(api.timer);
                                                if (e.type !== 'mouseover') {
                                                    api.timer = setTimeout(function() {
                                                        api.hide(e);
                                                    }, payload.duration);
                                                }
                                            })
                                            .triggerHandler('mouseout');
                                    }
                                }
                            }
                        });
                    },
                    scope.$on('notification.notify', function(event, payload) {
                        scope.addNotification(payload);
                    });
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/notification/service.snNotification.js */
    angular.module('sn.common.notification').factory('snNotification', function($document, $templateCache, $compile, $rootScope,
        $timeout, $q, getTemplateUrl, $http) {
        'use strict';
        var openNotifications = [],
            timeouts = {},
            options = {
                top: 20,
                gap: 10,
                duration: 5000
            };
        return {
            show: function(type, message, duration, onClick) {
                return createNotificationElement(type, message).then(function(element) {
                    displayNotification(element);
                    checkAndSetDestroyDuration(element, duration);
                    return element;
                });
            },
            hide: hide,
            setOptions: function(opts) {
                if (angular.isObject(opts))
                    angular.extend(options, opts);
            }
        };
    
        function getTemplate() {
            var templateName = 'sn_notification.xml',
                template = $templateCache.get(templateName),
                deferred = $q.defer();
            if (!template) {
                var url = getTemplateUrl(templateName);
                $http.get(url).then(function(result) {
                        $templateCache.put(templateName, result.data);
                        deferred.resolve(result.data);
                    },
                    function(reason) {
                        return $q.reject(reason);
                    });
            } else
                deferred.resolve(template);
            return deferred.promise;
        }
    
        function createNotificationElement(type, message) {
            var thisScope, thisElement;
            return getTemplate().then(function(template) {
                thisScope = $rootScope.$new();
                thisScope.type = type;
                thisScope.message = message;
                thisElement = $compile(template)(thisScope);
                return angular.element(thisElement[0]);
            });
        }
    
        function displayNotification(element) {
            var body = $document.find('body'),
                id = 'elm' + Date.now(),
                pos;
            body.append(element);
            pos = options.top + openNotifications.length * getElementHeight(element);
            positionElement(element, pos);
            element.addClass('visible');
            element.attr('id', id);
            element.find('button').bind('click', function(e) {
                hideElement(element);
            });
            openNotifications.push(element);
            if (options.duration > 0)
                timeouts[id] = $timeout(function() {
                    hideNext();
                }, options.duration);
        }
    
        function hide(element) {
            $timeout.cancel(timeouts[element.attr('id')]);
            element.removeClass('visible');
            element.addClass('hidden');
            element.find('button').eq(0).unbind();
            element.scope().$destroy();
            element.remove();
            repositionAll();
        }
    
        function hideElement(element) {
            var index = openNotifications.indexOf(element);
            openNotifications.splice(index, 1);
            hide(element);
        }
    
        function hideNext() {
            var element = openNotifications.shift();
            if (element)
                hide(element);
        }
    
        function getElementHeight(element) {
            return element[0].offsetHeight + options.gap;
        }
    
        function positionElement(element, pos) {
            element[0].style.top = pos + 'px';
        }
    
        function repositionAll() {
            var pos = options.top;
            openNotifications.forEach(function(element) {
                positionElement(element, pos);
                pos += getElementHeight(element);
            });
        }
    
        function checkAndSetDestroyDuration(element, duration) {
            if (duration) {
                timeouts[element.attr('id')] = $timeout(function() {
                    hideElement(element);
                }, duration);
            }
        }
    });;;
    /*! RESOURCE: /scripts/sn/common/presence/js_includes_presence.js */
    /*! RESOURCE: /scripts/js_includes_ng_amb.js */
    /*! RESOURCE: /scripts/js_includes_amb.js */
    /*! RESOURCE: /scripts/thirdparty/cometd/jquery/jquery-1.11.0.min.js */
    /*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
    ! function(a, b) {
        "object" == typeof module && "object" == typeof module.exports ? module.exports = a.document ? b(a, !0) : function(a) {
            if (!a.document) throw new Error("jQuery requires a window with a document");
            return b(a)
        } : b(a)
    }("undefined" != typeof window ? window : this, function(a, b) {
        var c = [],
            d = c.slice,
            e = c.concat,
            f = c.push,
            g = c.indexOf,
            h = {},
            i = h.toString,
            j = h.hasOwnProperty,
            k = "".trim,
            l = {},
            m = "1.11.0",
            n = function(a, b) {
                return new n.fn.init(a, b)
            },
            o = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
            p = /^-ms-/,
            q = /-([\da-z])/gi,
            r = function(a, b) {
                return b.toUpperCase()
            };
        n.fn = n.prototype = {
            jquery: m,
            constructor: n,
            selector: "",
            length: 0,
            toArray: function() {
                return d.call(this)
            },
            get: function(a) {
                return null != a ? 0 > a ? this[a + this.length] : this[a] : d.call(this)
            },
            pushStack: function(a) {
                var b = n.merge(this.constructor(), a);
                return b.prevObject = this, b.context = this.context, b
            },
            each: function(a, b) {
                return n.each(this, a, b)
            },
            map: function(a) {
                return this.pushStack(n.map(this, function(b, c) {
                    return a.call(b, c, b)
                }))
            },
            slice: function() {
                return this.pushStack(d.apply(this, arguments))
            },
            first: function() {
                return this.eq(0)
            },
            last: function() {
                return this.eq(-1)
            },
            eq: function(a) {
                var b = this.length,
                    c = +a + (0 > a ? b : 0);
                return this.pushStack(c >= 0 && b > c ? [this[c]] : [])
            },
            end: function() {
                return this.prevObject || this.constructor(null)
            },
            push: f,
            sort: c.sort,
            splice: c.splice
        }, n.extend = n.fn.extend = function() {
            var a, b, c, d, e, f, g = arguments[0] || {},
                h = 1,
                i = arguments.length,
                j = !1;
            for ("boolean" == typeof g && (j = g, g = arguments[h] || {}, h++), "object" == typeof g || n.isFunction(g) || (g = {}), h === i && (g = this, h--); i > h; h++)
                if (null != (e = arguments[h]))
                    for (d in e) a = g[d], c = e[d], g !== c && (j && c && (n.isPlainObject(c) || (b = n.isArray(c))) ? (b ? (b = !1, f = a && n.isArray(a) ? a : []) : f = a && n.isPlainObject(a) ? a : {}, g[d] = n.extend(j, f, c)) : void 0 !== c && (g[d] = c));
            return g
        }, n.extend({
            expando: "jQuery" + (m + Math.random()).replace(/\D/g, ""),
            isReady: !0,
            error: function(a) {
                throw new Error(a)
            },
            noop: function() {},
            isFunction: function(a) {
                return "function" === n.type(a)
            },
            isArray: Array.isArray || function(a) {
                return "array" === n.type(a)
            },
            isWindow: function(a) {
                return null != a && a == a.window
            },
            isNumeric: function(a) {
                return a - parseFloat(a) >= 0
            },
            isEmptyObject: function(a) {
                var b;
                for (b in a) return !1;
                return !0
            },
            isPlainObject: function(a) {
                var b;
                if (!a || "object" !== n.type(a) || a.nodeType || n.isWindow(a)) return !1;
                try {
                    if (a.constructor && !j.call(a, "constructor") && !j.call(a.constructor.prototype, "isPrototypeOf")) return !1
                } catch (c) {
                    return !1
                }
                if (l.ownLast)
                    for (b in a) return j.call(a, b);
                for (b in a);
                return void 0 === b || j.call(a, b)
            },
            type: function(a) {
                return null == a ? a + "" : "object" == typeof a || "function" == typeof a ? h[i.call(a)] || "object" : typeof a
            },
            globalEval: function(b) {
                b && n.trim(b) && (a.execScript || function(b) {
                    a.eval.call(a, b)
                })(b)
            },
            camelCase: function(a) {
                return a.replace(p, "ms-").replace(q, r)
            },
            nodeName: function(a, b) {
                return a.nodeName && a.nodeName.toLowerCase() === b.toLowerCase()
            },
            each: function(a, b, c) {
                var d, e = 0,
                    f = a.length,
                    g = s(a);
                if (c) {
                    if (g) {
                        for (; f > e; e++)
                            if (d = b.apply(a[e], c), d === !1) break
                    } else
                        for (e in a)
                            if (d = b.apply(a[e], c), d === !1) break
                } else if (g) {
                    for (; f > e; e++)
                        if (d = b.call(a[e], e, a[e]), d === !1) break
                } else
                    for (e in a)
                        if (d = b.call(a[e], e, a[e]), d === !1) break;
                return a
            },
            trim: k && !k.call("\ufeff\xa0") ? function(a) {
                return null == a ? "" : k.call(a)
            } : function(a) {
                return null == a ? "" : (a + "").replace(o, "")
            },
            makeArray: function(a, b) {
                var c = b || [];
                return null != a && (s(Object(a)) ? n.merge(c, "string" == typeof a ? [a] : a) : f.call(c, a)), c
            },
            inArray: function(a, b, c) {
                var d;
                if (b) {
                    if (g) return g.call(b, a, c);
                    for (d = b.length, c = c ? 0 > c ? Math.max(0, d + c) : c : 0; d > c; c++)
                        if (c in b && b[c] === a) return c
                }
                return -1
            },
            merge: function(a, b) {
                var c = +b.length,
                    d = 0,
                    e = a.length;
                while (c > d) a[e++] = b[d++];
                if (c !== c)
                    while (void 0 !== b[d]) a[e++] = b[d++];
                return a.length = e, a
            },
            grep: function(a, b, c) {
                for (var d, e = [], f = 0, g = a.length, h = !c; g > f; f++) d = !b(a[f], f), d !== h && e.push(a[f]);
                return e
            },
            map: function(a, b, c) {
                var d, f = 0,
                    g = a.length,
                    h = s(a),
                    i = [];
                if (h)
                    for (; g > f; f++) d = b(a[f], f, c), null != d && i.push(d);
                else
                    for (f in a) d = b(a[f], f, c), null != d && i.push(d);
                return e.apply([], i)
            },
            guid: 1,
            proxy: function(a, b) {
                var c, e, f;
                return "string" == typeof b && (f = a[b], b = a, a = f), n.isFunction(a) ? (c = d.call(arguments, 2), e = function() {
                    return a.apply(b || this, c.concat(d.call(arguments)))
                }, e.guid = a.guid = a.guid || n.guid++, e) : void 0
            },
            now: function() {
                return +new Date
            },
            support: l
        }), n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(a, b) {
            h["[object " + b + "]"] = b.toLowerCase()
        });
    
        function s(a) {
            var b = a.length,
                c = n.type(a);
            return "function" === c || n.isWindow(a) ? !1 : 1 === a.nodeType && b ? !0 : "array" === c || 0 === b || "number" == typeof b && b > 0 && b - 1 in a
        }
        var t = function(a) {
            var b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s = "sizzle" + -new Date,
                t = a.document,
                u = 0,
                v = 0,
                w = eb(),
                x = eb(),
                y = eb(),
                z = function(a, b) {
                    return a === b && (j = !0), 0
                },
                A = "undefined",
                B = 1 << 31,
                C = {}.hasOwnProperty,
                D = [],
                E = D.pop,
                F = D.push,
                G = D.push,
                H = D.slice,
                I = D.indexOf || function(a) {
                    for (var b = 0, c = this.length; c > b; b++)
                        if (this[b] === a) return b;
                    return -1
                },
                J = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
                K = "[\\x20\\t\\r\\n\\f]",
                L = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
                M = L.replace("w", "w#"),
                N = "\\[" + K + "*(" + L + ")" + K + "*(?:([*^$|!~]?=)" + K + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + M + ")|)|)" + K + "*\\]",
                O = ":(" + L + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + N.replace(3, 8) + ")*)|.*)\\)|)",
                P = new RegExp("^" + K + "+|((?:^|[^\\\\])(?:\\\\.)*)" + K + "+$", "g"),
                Q = new RegExp("^" + K + "*," + K + "*"),
                R = new RegExp("^" + K + "*([>+~]|" + K + ")" + K + "*"),
                S = new RegExp("=" + K + "*([^\\]'\"]*?)" + K + "*\\]", "g"),
                T = new RegExp(O),
                U = new RegExp("^" + M + "$"),
                V = {
                    ID: new RegExp("^#(" + L + ")"),
                    CLASS: new RegExp("^\\.(" + L + ")"),
                    TAG: new RegExp("^(" + L.replace("w", "w*") + ")"),
                    ATTR: new RegExp("^" + N),
                    PSEUDO: new RegExp("^" + O),
                    CHILD: new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + K + "*(even|odd|(([+-]|)(\\d*)n|)" + K + "*(?:([+-]|)" + K + "*(\\d+)|))" + K + "*\\)|)", "i"),
                    bool: new RegExp("^(?:" + J + ")$", "i"),
                    needsContext: new RegExp("^" + K + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + K + "*((?:-\\d)?\\d*)" + K + "*\\)|)(?=[^-]|$)", "i")
                },
                W = /^(?:input|select|textarea|button)$/i,
                X = /^h\d$/i,
                Y = /^[^{]+\{\s*\[native \w/,
                Z = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
                $ = /[+~]/,
                _ = /'|\\/g,
                ab = new RegExp("\\\\([\\da-f]{1,6}" + K + "?|(" + K + ")|.)", "ig"),
                bb = function(a, b, c) {
                    var d = "0x" + b - 65536;
                    return d !== d || c ? b : 0 > d ? String.fromCharCode(d + 65536) : String.fromCharCode(d >> 10 | 55296, 1023 & d | 56320)
                };
            try {
                G.apply(D = H.call(t.childNodes), t.childNodes), D[t.childNodes.length].nodeType
            } catch (cb) {
                G = {
                    apply: D.length ? function(a, b) {
                        F.apply(a, H.call(b))
                    } : function(a, b) {
                        var c = a.length,
                            d = 0;
                        while (a[c++] = b[d++]);
                        a.length = c - 1
                    }
                }
            }
    
            function db(a, b, d, e) {
                var f, g, h, i, j, m, p, q, u, v;
                if ((b ? b.ownerDocument || b : t) !== l && k(b), b = b || l, d = d || [], !a || "string" != typeof a) return d;
                if (1 !== (i = b.nodeType) && 9 !== i) return [];
                if (n && !e) {
                    if (f = Z.exec(a))
                        if (h = f[1]) {
                            if (9 === i) {
                                if (g = b.getElementById(h), !g || !g.parentNode) return d;
                                if (g.id === h) return d.push(g), d
                            } else if (b.ownerDocument && (g = b.ownerDocument.getElementById(h)) && r(b, g) && g.id === h) return d.push(g), d
                        } else {
                            if (f[2]) return G.apply(d, b.getElementsByTagName(a)), d;
                            if ((h = f[3]) && c.getElementsByClassName && b.getElementsByClassName) return G.apply(d, b.getElementsByClassName(h)), d
                        }
                    if (c.qsa && (!o || !o.test(a))) {
                        if (q = p = s, u = b, v = 9 === i && a, 1 === i && "object" !== b.nodeName.toLowerCase()) {
                            m = ob(a), (p = b.getAttribute("id")) ? q = p.replace(_, "\\$&") : b.setAttribute("id", q), q = "[id='" + q + "'] ", j = m.length;
                            while (j--) m[j] = q + pb(m[j]);
                            u = $.test(a) && mb(b.parentNode) || b, v = m.join(",")
                        }
                        if (v) try {
                            return G.apply(d, u.querySelectorAll(v)), d
                        } catch (w) {} finally {
                            p || b.removeAttribute("id")
                        }
                    }
                }
                return xb(a.replace(P, "$1"), b, d, e)
            }
    
            function eb() {
                var a = [];
    
                function b(c, e) {
                    return a.push(c + " ") > d.cacheLength && delete b[a.shift()], b[c + " "] = e
                }
                return b
            }
    
            function fb(a) {
                return a[s] = !0, a
            }
    
            function gb(a) {
                var b = l.createElement("div");
                try {
                    return !!a(b)
                } catch (c) {
                    return !1
                } finally {
                    b.parentNode && b.parentNode.removeChild(b), b = null
                }
            }
    
            function hb(a, b) {
                var c = a.split("|"),
                    e = a.length;
                while (e--) d.attrHandle[c[e]] = b
            }
    
            function ib(a, b) {
                var c = b && a,
                    d = c && 1 === a.nodeType && 1 === b.nodeType && (~b.sourceIndex || B) - (~a.sourceIndex || B);
                if (d) return d;
                if (c)
                    while (c = c.nextSibling)
                        if (c === b) return -1;
                return a ? 1 : -1
            }
    
            function jb(a) {
                return function(b) {
                    var c = b.nodeName.toLowerCase();
                    return "input" === c && b.type === a
                }
            }
    
            function kb(a) {
                return function(b) {
                    var c = b.nodeName.toLowerCase();
                    return ("input" === c || "button" === c) && b.type === a
                }
            }
    
            function lb(a) {
                return fb(function(b) {
                    return b = +b, fb(function(c, d) {
                        var e, f = a([], c.length, b),
                            g = f.length;
                        while (g--) c[e = f[g]] && (c[e] = !(d[e] = c[e]))
                    })
                })
            }
    
            function mb(a) {
                return a && typeof a.getElementsByTagName !== A && a
            }
            c = db.support = {}, f = db.isXML = function(a) {
                var b = a && (a.ownerDocument || a).documentElement;
                return b ? "HTML" !== b.nodeName : !1
            }, k = db.setDocument = function(a) {
                var b, e = a ? a.ownerDocument || a : t,
                    g = e.defaultView;
                return e !== l && 9 === e.nodeType && e.documentElement ? (l = e, m = e.documentElement, n = !f(e), g && g !== g.top && (g.addEventListener ? g.addEventListener("unload", function() {
                    k()
                }, !1) : g.attachEvent && g.attachEvent("onunload", function() {
                    k()
                })), c.attributes = gb(function(a) {
                    return a.className = "i", !a.getAttribute("className")
                }), c.getElementsByTagName = gb(function(a) {
                    return a.appendChild(e.createComment("")), !a.getElementsByTagName("*").length
                }), c.getElementsByClassName = Y.test(e.getElementsByClassName) && gb(function(a) {
                    return a.innerHTML = "<div class='a'></div><div class='a i'></div>", a.firstChild.className = "i", 2 === a.getElementsByClassName("i").length
                }), c.getById = gb(function(a) {
                    return m.appendChild(a).id = s, !e.getElementsByName || !e.getElementsByName(s).length
                }), c.getById ? (d.find.ID = function(a, b) {
                    if (typeof b.getElementById !== A && n) {
                        var c = b.getElementById(a);
                        return c && c.parentNode ? [c] : []
                    }
                }, d.filter.ID = function(a) {
                    var b = a.replace(ab, bb);
                    return function(a) {
                        return a.getAttribute("id") === b
                    }
                }) : (delete d.find.ID, d.filter.ID = function(a) {
                    var b = a.replace(ab, bb);
                    return function(a) {
                        var c = typeof a.getAttributeNode !== A && a.getAttributeNode("id");
                        return c && c.value === b
                    }
                }), d.find.TAG = c.getElementsByTagName ? function(a, b) {
                    return typeof b.getElementsByTagName !== A ? b.getElementsByTagName(a) : void 0
                } : function(a, b) {
                    var c, d = [],
                        e = 0,
                        f = b.getElementsByTagName(a);
                    if ("*" === a) {
                        while (c = f[e++]) 1 === c.nodeType && d.push(c);
                        return d
                    }
                    return f
                }, d.find.CLASS = c.getElementsByClassName && function(a, b) {
                    return typeof b.getElementsByClassName !== A && n ? b.getElementsByClassName(a) : void 0
                }, p = [], o = [], (c.qsa = Y.test(e.querySelectorAll)) && (gb(function(a) {
                    a.innerHTML = "<select t=''><option selected=''></option></select>", a.querySelectorAll("[t^='']").length && o.push("[*^$]=" + K + "*(?:''|\"\")"), a.querySelectorAll("[selected]").length || o.push("\\[" + K + "*(?:value|" + J + ")"), a.querySelectorAll(":checked").length || o.push(":checked")
                }), gb(function(a) {
                    var b = e.createElement("input");
                    b.setAttribute("type", "hidden"), a.appendChild(b).setAttribute("name", "D"), a.querySelectorAll("[name=d]").length && o.push("name" + K + "*[*^$|!~]?="), a.querySelectorAll(":enabled").length || o.push(":enabled", ":disabled"), a.querySelectorAll("*,:x"), o.push(",.*:")
                })), (c.matchesSelector = Y.test(q = m.webkitMatchesSelector || m.mozMatchesSelector || m.oMatchesSelector || m.msMatchesSelector)) && gb(function(a) {
                    c.disconnectedMatch = q.call(a, "div"), q.call(a, "[s!='']:x"), p.push("!=", O)
                }), o = o.length && new RegExp(o.join("|")), p = p.length && new RegExp(p.join("|")), b = Y.test(m.compareDocumentPosition), r = b || Y.test(m.contains) ? function(a, b) {
                    var c = 9 === a.nodeType ? a.documentElement : a,
                        d = b && b.parentNode;
                    return a === d || !(!d || 1 !== d.nodeType || !(c.contains ? c.contains(d) : a.compareDocumentPosition && 16 & a.compareDocumentPosition(d)))
                } : function(a, b) {
                    if (b)
                        while (b = b.parentNode)
                            if (b === a) return !0;
                    return !1
                }, z = b ? function(a, b) {
                    if (a === b) return j = !0, 0;
                    var d = !a.compareDocumentPosition - !b.compareDocumentPosition;
                    return d ? d : (d = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1, 1 & d || !c.sortDetached && b.compareDocumentPosition(a) === d ? a === e || a.ownerDocument === t && r(t, a) ? -1 : b === e || b.ownerDocument === t && r(t, b) ? 1 : i ? I.call(i, a) - I.call(i, b) : 0 : 4 & d ? -1 : 1)
                } : function(a, b) {
                    if (a === b) return j = !0, 0;
                    var c, d = 0,
                        f = a.parentNode,
                        g = b.parentNode,
                        h = [a],
                        k = [b];
                    if (!f || !g) return a === e ? -1 : b === e ? 1 : f ? -1 : g ? 1 : i ? I.call(i, a) - I.call(i, b) : 0;
                    if (f === g) return ib(a, b);
                    c = a;
                    while (c = c.parentNode) h.unshift(c);
                    c = b;
                    while (c = c.parentNode) k.unshift(c);
                    while (h[d] === k[d]) d++;
                    return d ? ib(h[d], k[d]) : h[d] === t ? -1 : k[d] === t ? 1 : 0
                }, e) : l
            }, db.matches = function(a, b) {
                return db(a, null, null, b)
            }, db.matchesSelector = function(a, b) {
                if ((a.ownerDocument || a) !== l && k(a), b = b.replace(S, "='$1']"), !(!c.matchesSelector || !n || p && p.test(b) || o && o.test(b))) try {
                    var d = q.call(a, b);
                    if (d || c.disconnectedMatch || a.document && 11 !== a.document.nodeType) return d
                } catch (e) {}
                return db(b, l, null, [a]).length > 0
            }, db.contains = function(a, b) {
                return (a.ownerDocument || a) !== l && k(a), r(a, b)
            }, db.attr = function(a, b) {
                (a.ownerDocument || a) !== l && k(a);
                var e = d.attrHandle[b.toLowerCase()],
                    f = e && C.call(d.attrHandle, b.toLowerCase()) ? e(a, b, !n) : void 0;
                return void 0 !== f ? f : c.attributes || !n ? a.getAttribute(b) : (f = a.getAttributeNode(b)) && f.specified ? f.value : null
            }, db.error = function(a) {
                throw new Error("Syntax error, unrecognized expression: " + a)
            }, db.uniqueSort = function(a) {
                var b, d = [],
                    e = 0,
                    f = 0;
                if (j = !c.detectDuplicates, i = !c.sortStable && a.slice(0), a.sort(z), j) {
                    while (b = a[f++]) b === a[f] && (e = d.push(f));
                    while (e--) a.splice(d[e], 1)
                }
                return i = null, a
            }, e = db.getText = function(a) {
                var b, c = "",
                    d = 0,
                    f = a.nodeType;
                if (f) {
                    if (1 === f || 9 === f || 11 === f) {
                        if ("string" == typeof a.textContent) return a.textContent;
                        for (a = a.firstChild; a; a = a.nextSibling) c += e(a)
                    } else if (3 === f || 4 === f) return a.nodeValue
                } else
                    while (b = a[d++]) c += e(b);
                return c
            }, d = db.selectors = {
                cacheLength: 50,
                createPseudo: fb,
                match: V,
                attrHandle: {},
                find: {},
                relative: {
                    ">": {
                        dir: "parentNode",
                        first: !0
                    },
                    " ": {
                        dir: "parentNode"
                    },
                    "+": {
                        dir: "previousSibling",
                        first: !0
                    },
                    "~": {
                        dir: "previousSibling"
                    }
                },
                preFilter: {
                    ATTR: function(a) {
                        return a[1] = a[1].replace(ab, bb), a[3] = (a[4] || a[5] || "").replace(ab, bb), "~=" === a[2] && (a[3] = " " + a[3] + " "), a.slice(0, 4)
                    },
                    CHILD: function(a) {
                        return a[1] = a[1].toLowerCase(), "nth" === a[1].slice(0, 3) ? (a[3] || db.error(a[0]), a[4] = +(a[4] ? a[5] + (a[6] || 1) : 2 * ("even" === a[3] || "odd" === a[3])), a[5] = +(a[7] + a[8] || "odd" === a[3])) : a[3] && db.error(a[0]), a
                    },
                    PSEUDO: function(a) {
                        var b, c = !a[5] && a[2];
                        return V.CHILD.test(a[0]) ? null : (a[3] && void 0 !== a[4] ? a[2] = a[4] : c && T.test(c) && (b = ob(c, !0)) && (b = c.indexOf(")", c.length - b) - c.length) && (a[0] = a[0].slice(0, b), a[2] = c.slice(0, b)), a.slice(0, 3))
                    }
                },
                filter: {
                    TAG: function(a) {
                        var b = a.replace(ab, bb).toLowerCase();
                        return "*" === a ? function() {
                            return !0
                        } : function(a) {
                            return a.nodeName && a.nodeName.toLowerCase() === b
                        }
                    },
                    CLASS: function(a) {
                        var b = w[a + " "];
                        return b || (b = new RegExp("(^|" + K + ")" + a + "(" + K + "|$)")) && w(a, function(a) {
                            return b.test("string" == typeof a.className && a.className || typeof a.getAttribute !== A && a.getAttribute("class") || "")
                        })
                    },
                    ATTR: function(a, b, c) {
                        return function(d) {
                            var e = db.attr(d, a);
                            return null == e ? "!=" === b : b ? (e += "", "=" === b ? e === c : "!=" === b ? e !== c : "^=" === b ? c && 0 === e.indexOf(c) : "*=" === b ? c && e.indexOf(c) > -1 : "$=" === b ? c && e.slice(-c.length) === c : "~=" === b ? (" " + e + " ").indexOf(c) > -1 : "|=" === b ? e === c || e.slice(0, c.length + 1) === c + "-" : !1) : !0
                        }
                    },
                    CHILD: function(a, b, c, d, e) {
                        var f = "nth" !== a.slice(0, 3),
                            g = "last" !== a.slice(-4),
                            h = "of-type" === b;
                        return 1 === d && 0 === e ? function(a) {
                            return !!a.parentNode
                        } : function(b, c, i) {
                            var j, k, l, m, n, o, p = f !== g ? "nextSibling" : "previousSibling",
                                q = b.parentNode,
                                r = h && b.nodeName.toLowerCase(),
                                t = !i && !h;
                            if (q) {
                                if (f) {
                                    while (p) {
                                        l = b;
                                        while (l = l[p])
                                            if (h ? l.nodeName.toLowerCase() === r : 1 === l.nodeType) return !1;
                                        o = p = "only" === a && !o && "nextSibling"
                                    }
                                    return !0
                                }
                                if (o = [g ? q.firstChild : q.lastChild], g && t) {
                                    k = q[s] || (q[s] = {}), j = k[a] || [], n = j[0] === u && j[1], m = j[0] === u && j[2], l = n && q.childNodes[n];
                                    while (l = ++n && l && l[p] || (m = n = 0) || o.pop())
                                        if (1 === l.nodeType && ++m && l === b) {
                                            k[a] = [u, n, m];
                                            break
                                        }
                                } else if (t && (j = (b[s] || (b[s] = {}))[a]) && j[0] === u) m = j[1];
                                else
                                    while (l = ++n && l && l[p] || (m = n = 0) || o.pop())
                                        if ((h ? l.nodeName.toLowerCase() === r : 1 === l.nodeType) && ++m && (t && ((l[s] || (l[s] = {}))[a] = [u, m]), l === b)) break;
                                return m -= e, m === d || m % d === 0 && m / d >= 0
                            }
                        }
                    },
                    PSEUDO: function(a, b) {
                        var c, e = d.pseudos[a] || d.setFilters[a.toLowerCase()] || db.error("unsupported pseudo: " + a);
                        return e[s] ? e(b) : e.length > 1 ? (c = [a, a, "", b], d.setFilters.hasOwnProperty(a.toLowerCase()) ? fb(function(a, c) {
                            var d, f = e(a, b),
                                g = f.length;
                            while (g--) d = I.call(a, f[g]), a[d] = !(c[d] = f[g])
                        }) : function(a) {
                            return e(a, 0, c)
                        }) : e
                    }
                },
                pseudos: {
                    not: fb(function(a) {
                        var b = [],
                            c = [],
                            d = g(a.replace(P, "$1"));
                        return d[s] ? fb(function(a, b, c, e) {
                            var f, g = d(a, null, e, []),
                                h = a.length;
                            while (h--)(f = g[h]) && (a[h] = !(b[h] = f))
                        }) : function(a, e, f) {
                            return b[0] = a, d(b, null, f, c), !c.pop()
                        }
                    }),
                    has: fb(function(a) {
                        return function(b) {
                            return db(a, b).length > 0
                        }
                    }),
                    contains: fb(function(a) {
                        return function(b) {
                            return (b.textContent || b.innerText || e(b)).indexOf(a) > -1
                        }
                    }),
                    lang: fb(function(a) {
                        return U.test(a || "") || db.error("unsupported lang: " + a), a = a.replace(ab, bb).toLowerCase(),
                            function(b) {
                                var c;
                                do
                                    if (c = n ? b.lang : b.getAttribute("xml:lang") || b.getAttribute("lang")) return c = c.toLowerCase(), c === a || 0 === c.indexOf(a + "-"); while ((b = b.parentNode) && 1 === b.nodeType);
                                return !1
                            }
                    }),
                    target: function(b) {
                        var c = a.location && a.location.hash;
                        return c && c.slice(1) === b.id
                    },
                    root: function(a) {
                        return a === m
                    },
                    focus: function(a) {
                        return a === l.activeElement && (!l.hasFocus || l.hasFocus()) && !!(a.type || a.href || ~a.tabIndex)
                    },
                    enabled: function(a) {
                        return a.disabled === !1
                    },
                    disabled: function(a) {
                        return a.disabled === !0
                    },
                    checked: function(a) {
                        var b = a.nodeName.toLowerCase();
                        return "input" === b && !!a.checked || "option" === b && !!a.selected
                    },
                    selected: function(a) {
                        return a.parentNode && a.parentNode.selectedIndex, a.selected === !0
                    },
                    empty: function(a) {
                        for (a = a.firstChild; a; a = a.nextSibling)
                            if (a.nodeType < 6) return !1;
                        return !0
                    },
                    parent: function(a) {
                        return !d.pseudos.empty(a)
                    },
                    header: function(a) {
                        return X.test(a.nodeName)
                    },
                    input: function(a) {
                        return W.test(a.nodeName)
                    },
                    button: function(a) {
                        var b = a.nodeName.toLowerCase();
                        return "input" === b && "button" === a.type || "button" === b
                    },
                    text: function(a) {
                        var b;
                        return "input" === a.nodeName.toLowerCase() && "text" === a.type && (null == (b = a.getAttribute("type")) || "text" === b.toLowerCase())
                    },
                    first: lb(function() {
                        return [0]
                    }),
                    last: lb(function(a, b) {
                        return [b - 1]
                    }),
                    eq: lb(function(a, b, c) {
                        return [0 > c ? c + b : c]
                    }),
                    even: lb(function(a, b) {
                        for (var c = 0; b > c; c += 2) a.push(c);
                        return a
                    }),
                    odd: lb(function(a, b) {
                        for (var c = 1; b > c; c += 2) a.push(c);
                        return a
                    }),
                    lt: lb(function(a, b, c) {
                        for (var d = 0 > c ? c + b : c; --d >= 0;) a.push(d);
                        return a
                    }),
                    gt: lb(function(a, b, c) {
                        for (var d = 0 > c ? c + b : c; ++d < b;) a.push(d);
                        return a
                    })
                }
            }, d.pseudos.nth = d.pseudos.eq;
            for (b in {
                    radio: !0,
                    checkbox: !0,
                    file: !0,
                    password: !0,
                    image: !0
                }) d.pseudos[b] = jb(b);
            for (b in {
                    submit: !0,
                    reset: !0
                }) d.pseudos[b] = kb(b);
    
            function nb() {}
            nb.prototype = d.filters = d.pseudos, d.setFilters = new nb;
    
            function ob(a, b) {
                var c, e, f, g, h, i, j, k = x[a + " "];
                if (k) return b ? 0 : k.slice(0);
                h = a, i = [], j = d.preFilter;
                while (h) {
                    (!c || (e = Q.exec(h))) && (e && (h = h.slice(e[0].length) || h), i.push(f = [])), c = !1, (e = R.exec(h)) && (c = e.shift(), f.push({
                        value: c,
                        type: e[0].replace(P, " ")
                    }), h = h.slice(c.length));
                    for (g in d.filter) !(e = V[g].exec(h)) || j[g] && !(e = j[g](e)) || (c = e.shift(), f.push({
                        value: c,
                        type: g,
                        matches: e
                    }), h = h.slice(c.length));
                    if (!c) break
                }
                return b ? h.length : h ? db.error(a) : x(a, i).slice(0)
            }
    
            function pb(a) {
                for (var b = 0, c = a.length, d = ""; c > b; b++) d += a[b].value;
                return d
            }
    
            function qb(a, b, c) {
                var d = b.dir,
                    e = c && "parentNode" === d,
                    f = v++;
                return b.first ? function(b, c, f) {
                    while (b = b[d])
                        if (1 === b.nodeType || e) return a(b, c, f)
                } : function(b, c, g) {
                    var h, i, j = [u, f];
                    if (g) {
                        while (b = b[d])
                            if ((1 === b.nodeType || e) && a(b, c, g)) return !0
                    } else
                        while (b = b[d])
                            if (1 === b.nodeType || e) {
                                if (i = b[s] || (b[s] = {}), (h = i[d]) && h[0] === u && h[1] === f) return j[2] = h[2];
                                if (i[d] = j, j[2] = a(b, c, g)) return !0
                            }
                }
            }
    
            function rb(a) {
                return a.length > 1 ? function(b, c, d) {
                    var e = a.length;
                    while (e--)
                        if (!a[e](b, c, d)) return !1;
                    return !0
                } : a[0]
            }
    
            function sb(a, b, c, d, e) {
                for (var f, g = [], h = 0, i = a.length, j = null != b; i > h; h++)(f = a[h]) && (!c || c(f, d, e)) && (g.push(f), j && b.push(h));
                return g
            }
    
            function tb(a, b, c, d, e, f) {
                return d && !d[s] && (d = tb(d)), e && !e[s] && (e = tb(e, f)), fb(function(f, g, h, i) {
                    var j, k, l, m = [],
                        n = [],
                        o = g.length,
                        p = f || wb(b || "*", h.nodeType ? [h] : h, []),
                        q = !a || !f && b ? p : sb(p, m, a, h, i),
                        r = c ? e || (f ? a : o || d) ? [] : g : q;
                    if (c && c(q, r, h, i), d) {
                        j = sb(r, n), d(j, [], h, i), k = j.length;
                        while (k--)(l = j[k]) && (r[n[k]] = !(q[n[k]] = l))
                    }
                    if (f) {
                        if (e || a) {
                            if (e) {
                                j = [], k = r.length;
                                while (k--)(l = r[k]) && j.push(q[k] = l);
                                e(null, r = [], j, i)
                            }
                            k = r.length;
                            while (k--)(l = r[k]) && (j = e ? I.call(f, l) : m[k]) > -1 && (f[j] = !(g[j] = l))
                        }
                    } else r = sb(r === g ? r.splice(o, r.length) : r), e ? e(null, g, r, i) : G.apply(g, r)
                })
            }
    
            function ub(a) {
                for (var b, c, e, f = a.length, g = d.relative[a[0].type], i = g || d.relative[" "], j = g ? 1 : 0, k = qb(function(a) {
                        return a === b
                    }, i, !0), l = qb(function(a) {
                        return I.call(b, a) > -1
                    }, i, !0), m = [function(a, c, d) {
                        return !g && (d || c !== h) || ((b = c).nodeType ? k(a, c, d) : l(a, c, d))
                    }]; f > j; j++)
                    if (c = d.relative[a[j].type]) m = [qb(rb(m), c)];
                    else {
                        if (c = d.filter[a[j].type].apply(null, a[j].matches), c[s]) {
                            for (e = ++j; f > e; e++)
                                if (d.relative[a[e].type]) break;
                            return tb(j > 1 && rb(m), j > 1 && pb(a.slice(0, j - 1).concat({
                                value: " " === a[j - 2].type ? "*" : ""
                            })).replace(P, "$1"), c, e > j && ub(a.slice(j, e)), f > e && ub(a = a.slice(e)), f > e && pb(a))
                        }
                        m.push(c)
                    }
                return rb(m)
            }
    
            function vb(a, b) {
                var c = b.length > 0,
                    e = a.length > 0,
                    f = function(f, g, i, j, k) {
                        var m, n, o, p = 0,
                            q = "0",
                            r = f && [],
                            s = [],
                            t = h,
                            v = f || e && d.find.TAG("*", k),
                            w = u += null == t ? 1 : Math.random() || .1,
                            x = v.length;
                        for (k && (h = g !== l && g); q !== x && null != (m = v[q]); q++) {
                            if (e && m) {
                                n = 0;
                                while (o = a[n++])
                                    if (o(m, g, i)) {
                                        j.push(m);
                                        break
                                    }
                                k && (u = w)
                            }
                            c && ((m = !o && m) && p--, f && r.push(m))
                        }
                        if (p += q, c && q !== p) {
                            n = 0;
                            while (o = b[n++]) o(r, s, g, i);
                            if (f) {
                                if (p > 0)
                                    while (q--) r[q] || s[q] || (s[q] = E.call(j));
                                s = sb(s)
                            }
                            G.apply(j, s), k && !f && s.length > 0 && p + b.length > 1 && db.uniqueSort(j)
                        }
                        return k && (u = w, h = t), r
                    };
                return c ? fb(f) : f
            }
            g = db.compile = function(a, b) {
                var c, d = [],
                    e = [],
                    f = y[a + " "];
                if (!f) {
                    b || (b = ob(a)), c = b.length;
                    while (c--) f = ub(b[c]), f[s] ? d.push(f) : e.push(f);
                    f = y(a, vb(e, d))
                }
                return f
            };
    
            function wb(a, b, c) {
                for (var d = 0, e = b.length; e > d; d++) db(a, b[d], c);
                return c
            }
    
            function xb(a, b, e, f) {
                var h, i, j, k, l, m = ob(a);
                if (!f && 1 === m.length) {
                    if (i = m[0] = m[0].slice(0), i.length > 2 && "ID" === (j = i[0]).type && c.getById && 9 === b.nodeType && n && d.relative[i[1].type]) {
                        if (b = (d.find.ID(j.matches[0].replace(ab, bb), b) || [])[0], !b) return e;
                        a = a.slice(i.shift().value.length)
                    }
                    h = V.needsContext.test(a) ? 0 : i.length;
                    while (h--) {
                        if (j = i[h], d.relative[k = j.type]) break;
                        if ((l = d.find[k]) && (f = l(j.matches[0].replace(ab, bb), $.test(i[0].type) && mb(b.parentNode) || b))) {
                            if (i.splice(h, 1), a = f.length && pb(i), !a) return G.apply(e, f), e;
                            break
                        }
                    }
                }
                return g(a, m)(f, b, !n, e, $.test(a) && mb(b.parentNode) || b), e
            }
            return c.sortStable = s.split("").sort(z).join("") === s, c.detectDuplicates = !!j, k(), c.sortDetached = gb(function(a) {
                return 1 & a.compareDocumentPosition(l.createElement("div"))
            }), gb(function(a) {
                return a.innerHTML = "<a href='#'></a>", "#" === a.firstChild.getAttribute("href")
            }) || hb("type|href|height|width", function(a, b, c) {
                return c ? void 0 : a.getAttribute(b, "type" === b.toLowerCase() ? 1 : 2)
            }), c.attributes && gb(function(a) {
                return a.innerHTML = "<input/>", a.firstChild.setAttribute("value", ""), "" === a.firstChild.getAttribute("value")
            }) || hb("value", function(a, b, c) {
                return c || "input" !== a.nodeName.toLowerCase() ? void 0 : a.defaultValue
            }), gb(function(a) {
                return null == a.getAttribute("disabled")
            }) || hb(J, function(a, b, c) {
                var d;
                return c ? void 0 : a[b] === !0 ? b.toLowerCase() : (d = a.getAttributeNode(b)) && d.specified ? d.value : null
            }), db
        }(a);
        n.find = t, n.expr = t.selectors, n.expr[":"] = n.expr.pseudos, n.unique = t.uniqueSort, n.text = t.getText, n.isXMLDoc = t.isXML, n.contains = t.contains;
        var u = n.expr.match.needsContext,
            v = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
            w = /^.[^:#\[\.,]*$/;
    
        function x(a, b, c) {
            if (n.isFunction(b)) return n.grep(a, function(a, d) {
                return !!b.call(a, d, a) !== c
            });
            if (b.nodeType) return n.grep(a, function(a) {
                return a === b !== c
            });
            if ("string" == typeof b) {
                if (w.test(b)) return n.filter(b, a, c);
                b = n.filter(b, a)
            }
            return n.grep(a, function(a) {
                return n.inArray(a, b) >= 0 !== c
            })
        }
        n.filter = function(a, b, c) {
            var d = b[0];
            return c && (a = ":not(" + a + ")"), 1 === b.length && 1 === d.nodeType ? n.find.matchesSelector(d, a) ? [d] : [] : n.find.matches(a, n.grep(b, function(a) {
                return 1 === a.nodeType
            }))
        }, n.fn.extend({
            find: function(a) {
                var b, c = [],
                    d = this,
                    e = d.length;
                if ("string" != typeof a) return this.pushStack(n(a).filter(function() {
                    for (b = 0; e > b; b++)
                        if (n.contains(d[b], this)) return !0
                }));
                for (b = 0; e > b; b++) n.find(a, d[b], c);
                return c = this.pushStack(e > 1 ? n.unique(c) : c), c.selector = this.selector ? this.selector + " " + a : a, c
            },
            filter: function(a) {
                return this.pushStack(x(this, a || [], !1))
            },
            not: function(a) {
                return this.pushStack(x(this, a || [], !0))
            },
            is: function(a) {
                return !!x(this, "string" == typeof a && u.test(a) ? n(a) : a || [], !1).length
            }
        });
        var y, z = a.document,
            A = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
            B = n.fn.init = function(a, b) {
                var c, d;
                if (!a) return this;
                if ("string" == typeof a) {
                    if (c = "<" === a.charAt(0) && ">" === a.charAt(a.length - 1) && a.length >= 3 ? [null, a, null] : A.exec(a), !c || !c[1] && b) return !b || b.jquery ? (b || y).find(a) : this.constructor(b).find(a);
                    if (c[1]) {
                        if (b = b instanceof n ? b[0] : b, n.merge(this, n.parseHTML(c[1], b && b.nodeType ? b.ownerDocument || b : z, !0)), v.test(c[1]) && n.isPlainObject(b))
                            for (c in b) n.isFunction(this[c]) ? this[c](b[c]) : this.attr(c, b[c]);
                        return this
                    }
                    if (d = z.getElementById(c[2]), d && d.parentNode) {
                        if (d.id !== c[2]) return y.find(a);
                        this.length = 1, this[0] = d
                    }
                    return this.context = z, this.selector = a, this
                }
                return a.nodeType ? (this.context = this[0] = a, this.length = 1, this) : n.isFunction(a) ? "undefined" != typeof y.ready ? y.ready(a) : a(n) : (void 0 !== a.selector && (this.selector = a.selector, this.context = a.context), n.makeArray(a, this))
            };
        B.prototype = n.fn, y = n(z);
        var C = /^(?:parents|prev(?:Until|All))/,
            D = {
                children: !0,
                contents: !0,
                next: !0,
                prev: !0
            };
        n.extend({
            dir: function(a, b, c) {
                var d = [],
                    e = a[b];
                while (e && 9 !== e.nodeType && (void 0 === c || 1 !== e.nodeType || !n(e).is(c))) 1 === e.nodeType && d.push(e), e = e[b];
                return d
            },
            sibling: function(a, b) {
                for (var c = []; a; a = a.nextSibling) 1 === a.nodeType && a !== b && c.push(a);
                return c
            }
        }), n.fn.extend({
            has: function(a) {
                var b, c = n(a, this),
                    d = c.length;
                return this.filter(function() {
                    for (b = 0; d > b; b++)
                        if (n.contains(this, c[b])) return !0
                })
            },
            closest: function(a, b) {
                for (var c, d = 0, e = this.length, f = [], g = u.test(a) || "string" != typeof a ? n(a, b || this.context) : 0; e > d; d++)
                    for (c = this[d]; c && c !== b; c = c.parentNode)
                        if (c.nodeType < 11 && (g ? g.index(c) > -1 : 1 === c.nodeType && n.find.matchesSelector(c, a))) {
                            f.push(c);
                            break
                        }
                return this.pushStack(f.length > 1 ? n.unique(f) : f)
            },
            index: function(a) {
                return a ? "string" == typeof a ? n.inArray(this[0], n(a)) : n.inArray(a.jquery ? a[0] : a, this) : this[0] && this[0].parentNode ? this.first().prevAll().length : -1
            },
            add: function(a, b) {
                return this.pushStack(n.unique(n.merge(this.get(), n(a, b))))
            },
            addBack: function(a) {
                return this.add(null == a ? this.prevObject : this.prevObject.filter(a))
            }
        });
    
        function E(a, b) {
            do a = a[b]; while (a && 1 !== a.nodeType);
            return a
        }
        n.each({
            parent: function(a) {
                var b = a.parentNode;
                return b && 11 !== b.nodeType ? b : null
            },
            parents: function(a) {
                return n.dir(a, "parentNode")
            },
            parentsUntil: function(a, b, c) {
                return n.dir(a, "parentNode", c)
            },
            next: function(a) {
                return E(a, "nextSibling")
            },
            prev: function(a) {
                return E(a, "previousSibling")
            },
            nextAll: function(a) {
                return n.dir(a, "nextSibling")
            },
            prevAll: function(a) {
                return n.dir(a, "previousSibling")
            },
            nextUntil: function(a, b, c) {
                return n.dir(a, "nextSibling", c)
            },
            prevUntil: function(a, b, c) {
                return n.dir(a, "previousSibling", c)
            },
            siblings: function(a) {
                return n.sibling((a.parentNode || {}).firstChild, a)
            },
            children: function(a) {
                return n.sibling(a.firstChild)
            },
            contents: function(a) {
                return n.nodeName(a, "iframe") ? a.contentDocument || a.contentWindow.document : n.merge([], a.childNodes)
            }
        }, function(a, b) {
            n.fn[a] = function(c, d) {
                var e = n.map(this, b, c);
                return "Until" !== a.slice(-5) && (d = c), d && "string" == typeof d && (e = n.filter(d, e)), this.length > 1 && (D[a] || (e = n.unique(e)), C.test(a) && (e = e.reverse())), this.pushStack(e)
            }
        });
        var F = /\S+/g,
            G = {};
    
        function H(a) {
            var b = G[a] = {};
            return n.each(a.match(F) || [], function(a, c) {
                b[c] = !0
            }), b
        }
        n.Callbacks = function(a) {
            a = "string" == typeof a ? G[a] || H(a) : n.extend({}, a);
            var b, c, d, e, f, g, h = [],
                i = !a.once && [],
                j = function(l) {
                    for (c = a.memory && l, d = !0, f = g || 0, g = 0, e = h.length, b = !0; h && e > f; f++)
                        if (h[f].apply(l[0], l[1]) === !1 && a.stopOnFalse) {
                            c = !1;
                            break
                        }
                    b = !1, h && (i ? i.length && j(i.shift()) : c ? h = [] : k.disable())
                },
                k = {
                    add: function() {
                        if (h) {
                            var d = h.length;
                            ! function f(b) {
                                n.each(b, function(b, c) {
                                    var d = n.type(c);
                                    "function" === d ? a.unique && k.has(c) || h.push(c) : c && c.length && "string" !== d && f(c)
                                })
                            }(arguments), b ? e = h.length : c && (g = d, j(c))
                        }
                        return this
                    },
                    remove: function() {
                        return h && n.each(arguments, function(a, c) {
                            var d;
                            while ((d = n.inArray(c, h, d)) > -1) h.splice(d, 1), b && (e >= d && e--, f >= d && f--)
                        }), this
                    },
                    has: function(a) {
                        return a ? n.inArray(a, h) > -1 : !(!h || !h.length)
                    },
                    empty: function() {
                        return h = [], e = 0, this
                    },
                    disable: function() {
                        return h = i = c = void 0, this
                    },
                    disabled: function() {
                        return !h
                    },
                    lock: function() {
                        return i = void 0, c || k.disable(), this
                    },
                    locked: function() {
                        return !i
                    },
                    fireWith: function(a, c) {
                        return !h || d && !i || (c = c || [], c = [a, c.slice ? c.slice() : c], b ? i.push(c) : j(c)), this
                    },
                    fire: function() {
                        return k.fireWith(this, arguments), this
                    },
                    fired: function() {
                        return !!d
                    }
                };
            return k
        }, n.extend({
            Deferred: function(a) {
                var b = [
                        ["resolve", "done", n.Callbacks("once memory"), "resolved"],
                        ["reject", "fail", n.Callbacks("once memory"), "rejected"],
                        ["notify", "progress", n.Callbacks("memory")]
                    ],
                    c = "pending",
                    d = {
                        state: function() {
                            return c
                        },
                        always: function() {
                            return e.done(arguments).fail(arguments), this
                        },
                        then: function() {
                            var a = arguments;
                            return n.Deferred(function(c) {
                                n.each(b, function(b, f) {
                                    var g = n.isFunction(a[b]) && a[b];
                                    e[f[1]](function() {
                                        var a = g && g.apply(this, arguments);
                                        a && n.isFunction(a.promise) ? a.promise().done(c.resolve).fail(c.reject).progress(c.notify) : c[f[0] + "With"](this === d ? c.promise() : this, g ? [a] : arguments)
                                    })
                                }), a = null
                            }).promise()
                        },
                        promise: function(a) {
                            return null != a ? n.extend(a, d) : d
                        }
                    },
                    e = {};
                return d.pipe = d.then, n.each(b, function(a, f) {
                    var g = f[2],
                        h = f[3];
                    d[f[1]] = g.add, h && g.add(function() {
                        c = h
                    }, b[1 ^ a][2].disable, b[2][2].lock), e[f[0]] = function() {
                        return e[f[0] + "With"](this === e ? d : this, arguments), this
                    }, e[f[0] + "With"] = g.fireWith
                }), d.promise(e), a && a.call(e, e), e
            },
            when: function(a) {
                var b = 0,
                    c = d.call(arguments),
                    e = c.length,
                    f = 1 !== e || a && n.isFunction(a.promise) ? e : 0,
                    g = 1 === f ? a : n.Deferred(),
                    h = function(a, b, c) {
                        return function(e) {
                            b[a] = this, c[a] = arguments.length > 1 ? d.call(arguments) : e, c === i ? g.notifyWith(b, c) : --f || g.resolveWith(b, c)
                        }
                    },
                    i, j, k;
                if (e > 1)
                    for (i = new Array(e), j = new Array(e), k = new Array(e); e > b; b++) c[b] && n.isFunction(c[b].promise) ? c[b].promise().done(h(b, k, c)).fail(g.reject).progress(h(b, j, i)) : --f;
                return f || g.resolveWith(k, c), g.promise()
            }
        });
        var I;
        n.fn.ready = function(a) {
            return n.ready.promise().done(a), this
        }, n.extend({
            isReady: !1,
            readyWait: 1,
            holdReady: function(a) {
                a ? n.readyWait++ : n.ready(!0)
            },
            ready: function(a) {
                if (a === !0 ? !--n.readyWait : !n.isReady) {
                    if (!z.body) return setTimeout(n.ready);
                    n.isReady = !0, a !== !0 && --n.readyWait > 0 || (I.resolveWith(z, [n]), n.fn.trigger && n(z).trigger("ready").off("ready"))
                }
            }
        });
    
        function J() {
            z.addEventListener ? (z.removeEventListener("DOMContentLoaded", K, !1), a.removeEventListener("load", K, !1)) : (z.detachEvent("onreadystatechange", K), a.detachEvent("onload", K))
        }
    
        function K() {
            (z.addEventListener || "load" === event.type || "complete" === z.readyState) && (J(), n.ready())
        }
        n.ready.promise = function(b) {
            if (!I)
                if (I = n.Deferred(), "complete" === z.readyState) setTimeout(n.ready);
                else if (z.addEventListener) z.addEventListener("DOMContentLoaded", K, !1), a.addEventListener("load", K, !1);
            else {
                z.attachEvent("onreadystatechange", K), a.attachEvent("onload", K);
                var c = !1;
                try {
                    c = null == a.frameElement && z.documentElement
                } catch (d) {}
                c && c.doScroll && ! function e() {
                    if (!n.isReady) {
                        try {
                            c.doScroll("left")
                        } catch (a) {
                            return setTimeout(e, 50)
                        }
                        J(), n.ready()
                    }
                }()
            }
            return I.promise(b)
        };
        var L = "undefined",
            M;
        for (M in n(l)) break;
        l.ownLast = "0" !== M, l.inlineBlockNeedsLayout = !1, n(function() {
                var a, b, c = z.getElementsByTagName("body")[0];
                c && (a = z.createElement("div"), a.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px", b = z.createElement("div"), c.appendChild(a).appendChild(b), typeof b.style.zoom !== L && (b.style.cssText = "border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1", (l.inlineBlockNeedsLayout = 3 === b.offsetWidth) && (c.style.zoom = 1)), c.removeChild(a), a = b = null)
            }),
            function() {
                var a = z.createElement("div");
                if (null == l.deleteExpando) {
                    l.deleteExpando = !0;
                    try {
                        delete a.test
                    } catch (b) {
                        l.deleteExpando = !1
                    }
                }
                a = null
            }(), n.acceptData = function(a) {
                var b = n.noData[(a.nodeName + " ").toLowerCase()],
                    c = +a.nodeType || 1;
                return 1 !== c && 9 !== c ? !1 : !b || b !== !0 && a.getAttribute("classid") === b
            };
        var N = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
            O = /([A-Z])/g;
    
        function P(a, b, c) {
            if (void 0 === c && 1 === a.nodeType) {
                var d = "data-" + b.replace(O, "-$1").toLowerCase();
                if (c = a.getAttribute(d), "string" == typeof c) {
                    try {
                        c = "true" === c ? !0 : "false" === c ? !1 : "null" === c ? null : +c + "" === c ? +c : N.test(c) ? n.parseJSON(c) : c
                    } catch (e) {}
                    n.data(a, b, c)
                } else c = void 0
            }
            return c
        }
    
        function Q(a) {
            var b;
            for (b in a)
                if (("data" !== b || !n.isEmptyObject(a[b])) && "toJSON" !== b) return !1;
            return !0
        }
    
        function R(a, b, d, e) {
            if (n.acceptData(a)) {
                var f, g, h = n.expando,
                    i = a.nodeType,
                    j = i ? n.cache : a,
                    k = i ? a[h] : a[h] && h;
                if (k && j[k] && (e || j[k].data) || void 0 !== d || "string" != typeof b) return k || (k = i ? a[h] = c.pop() || n.guid++ : h), j[k] || (j[k] = i ? {} : {
                    toJSON: n.noop
                }), ("object" == typeof b || "function" == typeof b) && (e ? j[k] = n.extend(j[k], b) : j[k].data = n.extend(j[k].data, b)), g = j[k], e || (g.data || (g.data = {}), g = g.data), void 0 !== d && (g[n.camelCase(b)] = d), "string" == typeof b ? (f = g[b], null == f && (f = g[n.camelCase(b)])) : f = g, f
            }
        }
    
        function S(a, b, c) {
            if (n.acceptData(a)) {
                var d, e, f = a.nodeType,
                    g = f ? n.cache : a,
                    h = f ? a[n.expando] : n.expando;
                if (g[h]) {
                    if (b && (d = c ? g[h] : g[h].data)) {
                        n.isArray(b) ? b = b.concat(n.map(b, n.camelCase)) : b in d ? b = [b] : (b = n.camelCase(b), b = b in d ? [b] : b.split(" ")), e = b.length;
                        while (e--) delete d[b[e]];
                        if (c ? !Q(d) : !n.isEmptyObject(d)) return
                    }(c || (delete g[h].data, Q(g[h]))) && (f ? n.cleanData([a], !0) : l.deleteExpando || g != g.window ? delete g[h] : g[h] = null)
                }
            }
        }
        n.extend({
            cache: {},
            noData: {
                "applet ": !0,
                "embed ": !0,
                "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
            },
            hasData: function(a) {
                return a = a.nodeType ? n.cache[a[n.expando]] : a[n.expando], !!a && !Q(a)
            },
            data: function(a, b, c) {
                return R(a, b, c)
            },
            removeData: function(a, b) {
                return S(a, b)
            },
            _data: function(a, b, c) {
                return R(a, b, c, !0)
            },
            _removeData: function(a, b) {
                return S(a, b, !0)
            }
        }), n.fn.extend({
            data: function(a, b) {
                var c, d, e, f = this[0],
                    g = f && f.attributes;
                if (void 0 === a) {
                    if (this.length && (e = n.data(f), 1 === f.nodeType && !n._data(f, "parsedAttrs"))) {
                        c = g.length;
                        while (c--) d = g[c].name, 0 === d.indexOf("data-") && (d = n.camelCase(d.slice(5)), P(f, d, e[d]));
                        n._data(f, "parsedAttrs", !0)
                    }
                    return e
                }
                return "object" == typeof a ? this.each(function() {
                    n.data(this, a)
                }) : arguments.length > 1 ? this.each(function() {
                    n.data(this, a, b)
                }) : f ? P(f, a, n.data(f, a)) : void 0
            },
            removeData: function(a) {
                return this.each(function() {
                    n.removeData(this, a)
                })
            }
        }), n.extend({
            queue: function(a, b, c) {
                var d;
                return a ? (b = (b || "fx") + "queue", d = n._data(a, b), c && (!d || n.isArray(c) ? d = n._data(a, b, n.makeArray(c)) : d.push(c)), d || []) : void 0
            },
            dequeue: function(a, b) {
                b = b || "fx";
                var c = n.queue(a, b),
                    d = c.length,
                    e = c.shift(),
                    f = n._queueHooks(a, b),
                    g = function() {
                        n.dequeue(a, b)
                    };
                "inprogress" === e && (e = c.shift(), d--), e && ("fx" === b && c.unshift("inprogress"), delete f.stop, e.call(a, g, f)), !d && f && f.empty.fire()
            },
            _queueHooks: function(a, b) {
                var c = b + "queueHooks";
                return n._data(a, c) || n._data(a, c, {
                    empty: n.Callbacks("once memory").add(function() {
                        n._removeData(a, b + "queue"), n._removeData(a, c)
                    })
                })
            }
        }), n.fn.extend({
            queue: function(a, b) {
                var c = 2;
                return "string" != typeof a && (b = a, a = "fx", c--), arguments.length < c ? n.queue(this[0], a) : void 0 === b ? this : this.each(function() {
                    var c = n.queue(this, a, b);
                    n._queueHooks(this, a), "fx" === a && "inprogress" !== c[0] && n.dequeue(this, a)
                })
            },
            dequeue: function(a) {
                return this.each(function() {
                    n.dequeue(this, a)
                })
            },
            clearQueue: function(a) {
                return this.queue(a || "fx", [])
            },
            promise: function(a, b) {
                var c, d = 1,
                    e = n.Deferred(),
                    f = this,
                    g = this.length,
                    h = function() {
                        --d || e.resolveWith(f, [f])
                    };
                "string" != typeof a && (b = a, a = void 0), a = a || "fx";
                while (g--) c = n._data(f[g], a + "queueHooks"), c && c.empty && (d++, c.empty.add(h));
                return h(), e.promise(b)
            }
        });
        var T = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
            U = ["Top", "Right", "Bottom", "Left"],
            V = function(a, b) {
                return a = b || a, "none" === n.css(a, "display") || !n.contains(a.ownerDocument, a)
            },
            W = n.access = function(a, b, c, d, e, f, g) {
                var h = 0,
                    i = a.length,
                    j = null == c;
                if ("object" === n.type(c)) {
                    e = !0;
                    for (h in c) n.access(a, b, h, c[h], !0, f, g)
                } else if (void 0 !== d && (e = !0, n.isFunction(d) || (g = !0), j && (g ? (b.call(a, d), b = null) : (j = b, b = function(a, b, c) {
                        return j.call(n(a), c)
                    })), b))
                    for (; i > h; h++) b(a[h], c, g ? d : d.call(a[h], h, b(a[h], c)));
                return e ? a : j ? b.call(a) : i ? b(a[0], c) : f
            },
            X = /^(?:checkbox|radio)$/i;
        ! function() {
            var a = z.createDocumentFragment(),
                b = z.createElement("div"),
                c = z.createElement("input");
            if (b.setAttribute("className", "t"), b.innerHTML = "  <link/><table></table><a href='/a'>a</a>", l.leadingWhitespace = 3 === b.firstChild.nodeType, l.tbody = !b.getElementsByTagName("tbody").length, l.htmlSerialize = !!b.getElementsByTagName("link").length, l.html5Clone = "<:nav></:nav>" !== z.createElement("nav").cloneNode(!0).outerHTML, c.type = "checkbox", c.checked = !0, a.appendChild(c), l.appendChecked = c.checked, b.innerHTML = "<textarea>x</textarea>", l.noCloneChecked = !!b.cloneNode(!0).lastChild.defaultValue, a.appendChild(b), b.innerHTML = "<input type='radio' checked='checked' name='t'/>", l.checkClone = b.cloneNode(!0).cloneNode(!0).lastChild.checked, l.noCloneEvent = !0, b.attachEvent && (b.attachEvent("onclick", function() {
                    l.noCloneEvent = !1
                }), b.cloneNode(!0).click()), null == l.deleteExpando) {
                l.deleteExpando = !0;
                try {
                    delete b.test
                } catch (d) {
                    l.deleteExpando = !1
                }
            }
            a = b = c = null
        }(),
        function() {
            var b, c, d = z.createElement("div");
            for (b in {
                    submit: !0,
                    change: !0,
                    focusin: !0
                }) c = "on" + b, (l[b + "Bubbles"] = c in a) || (d.setAttribute(c, "t"), l[b + "Bubbles"] = d.attributes[c].expando === !1);
            d = null
        }();
        var Y = /^(?:input|select|textarea)$/i,
            Z = /^key/,
            $ = /^(?:mouse|contextmenu)|click/,
            _ = /^(?:focusinfocus|focusoutblur)$/,
            ab = /^([^.]*)(?:\.(.+)|)$/;
    
        function bb() {
            return !0
        }
    
        function cb() {
            return !1
        }
    
        function db() {
            try {
                return z.activeElement
            } catch (a) {}
        }
        n.event = {
            global: {},
            add: function(a, b, c, d, e) {
                var f, g, h, i, j, k, l, m, o, p, q, r = n._data(a);
                if (r) {
                    c.handler && (i = c, c = i.handler, e = i.selector), c.guid || (c.guid = n.guid++), (g = r.events) || (g = r.events = {}), (k = r.handle) || (k = r.handle = function(a) {
                        return typeof n === L || a && n.event.triggered === a.type ? void 0 : n.event.dispatch.apply(k.elem, arguments)
                    }, k.elem = a), b = (b || "").match(F) || [""], h = b.length;
                    while (h--) f = ab.exec(b[h]) || [], o = q = f[1], p = (f[2] || "").split(".").sort(), o && (j = n.event.special[o] || {}, o = (e ? j.delegateType : j.bindType) || o, j = n.event.special[o] || {}, l = n.extend({
                        type: o,
                        origType: q,
                        data: d,
                        handler: c,
                        guid: c.guid,
                        selector: e,
                        needsContext: e && n.expr.match.needsContext.test(e),
                        namespace: p.join(".")
                    }, i), (m = g[o]) || (m = g[o] = [], m.delegateCount = 0, j.setup && j.setup.call(a, d, p, k) !== !1 || (a.addEventListener ? a.addEventListener(o, k, !1) : a.attachEvent && a.attachEvent("on" + o, k))), j.add && (j.add.call(a, l), l.handler.guid || (l.handler.guid = c.guid)), e ? m.splice(m.delegateCount++, 0, l) : m.push(l), n.event.global[o] = !0);
                    a = null
                }
            },
            remove: function(a, b, c, d, e) {
                var f, g, h, i, j, k, l, m, o, p, q, r = n.hasData(a) && n._data(a);
                if (r && (k = r.events)) {
                    b = (b || "").match(F) || [""], j = b.length;
                    while (j--)
                        if (h = ab.exec(b[j]) || [], o = q = h[1], p = (h[2] || "").split(".").sort(), o) {
                            l = n.event.special[o] || {}, o = (d ? l.delegateType : l.bindType) || o, m = k[o] || [], h = h[2] && new RegExp("(^|\\.)" + p.join("\\.(?:.*\\.|)") + "(\\.|$)"), i = f = m.length;
                            while (f--) g = m[f], !e && q !== g.origType || c && c.guid !== g.guid || h && !h.test(g.namespace) || d && d !== g.selector && ("**" !== d || !g.selector) || (m.splice(f, 1), g.selector && m.delegateCount--, l.remove && l.remove.call(a, g));
                            i && !m.length && (l.teardown && l.teardown.call(a, p, r.handle) !== !1 || n.removeEvent(a, o, r.handle), delete k[o])
                        } else
                            for (o in k) n.event.remove(a, o + b[j], c, d, !0);
                    n.isEmptyObject(k) && (delete r.handle, n._removeData(a, "events"))
                }
            },
            trigger: function(b, c, d, e) {
                var f, g, h, i, k, l, m, o = [d || z],
                    p = j.call(b, "type") ? b.type : b,
                    q = j.call(b, "namespace") ? b.namespace.split(".") : [];
                if (h = l = d = d || z, 3 !== d.nodeType && 8 !== d.nodeType && !_.test(p + n.event.triggered) && (p.indexOf(".") >= 0 && (q = p.split("."), p = q.shift(), q.sort()), g = p.indexOf(":") < 0 && "on" + p, b = b[n.expando] ? b : new n.Event(p, "object" == typeof b && b), b.isTrigger = e ? 2 : 3, b.namespace = q.join("."), b.namespace_re = b.namespace ? new RegExp("(^|\\.)" + q.join("\\.(?:.*\\.|)") + "(\\.|$)") : null, b.result = void 0, b.target || (b.target = d), c = null == c ? [b] : n.makeArray(c, [b]), k = n.event.special[p] || {}, e || !k.trigger || k.trigger.apply(d, c) !== !1)) {
                    if (!e && !k.noBubble && !n.isWindow(d)) {
                        for (i = k.delegateType || p, _.test(i + p) || (h = h.parentNode); h; h = h.parentNode) o.push(h), l = h;
                        l === (d.ownerDocument || z) && o.push(l.defaultView || l.parentWindow || a)
                    }
                    m = 0;
                    while ((h = o[m++]) && !b.isPropagationStopped()) b.type = m > 1 ? i : k.bindType || p, f = (n._data(h, "events") || {})[b.type] && n._data(h, "handle"), f && f.apply(h, c), f = g && h[g], f && f.apply && n.acceptData(h) && (b.result = f.apply(h, c), b.result === !1 && b.preventDefault());
                    if (b.type = p, !e && !b.isDefaultPrevented() && (!k._default || k._default.apply(o.pop(), c) === !1) && n.acceptData(d) && g && d[p] && !n.isWindow(d)) {
                        l = d[g], l && (d[g] = null), n.event.triggered = p;
                        try {
                            d[p]()
                        } catch (r) {}
                        n.event.triggered = void 0, l && (d[g] = l)
                    }
                    return b.result
                }
            },
            dispatch: function(a) {
                a = n.event.fix(a);
                var b, c, e, f, g, h = [],
                    i = d.call(arguments),
                    j = (n._data(this, "events") || {})[a.type] || [],
                    k = n.event.special[a.type] || {};
                if (i[0] = a, a.delegateTarget = this, !k.preDispatch || k.preDispatch.call(this, a) !== !1) {
                    h = n.event.handlers.call(this, a, j), b = 0;
                    while ((f = h[b++]) && !a.isPropagationStopped()) {
                        a.currentTarget = f.elem, g = 0;
                        while ((e = f.handlers[g++]) && !a.isImmediatePropagationStopped())(!a.namespace_re || a.namespace_re.test(e.namespace)) && (a.handleObj = e, a.data = e.data, c = ((n.event.special[e.origType] || {}).handle || e.handler).apply(f.elem, i), void 0 !== c && (a.result = c) === !1 && (a.preventDefault(), a.stopPropagation()))
                    }
                    return k.postDispatch && k.postDispatch.call(this, a), a.result
                }
            },
            handlers: function(a, b) {
                var c, d, e, f, g = [],
                    h = b.delegateCount,
                    i = a.target;
                if (h && i.nodeType && (!a.button || "click" !== a.type))
                    for (; i != this; i = i.parentNode || this)
                        if (1 === i.nodeType && (i.disabled !== !0 || "click" !== a.type)) {
                            for (e = [], f = 0; h > f; f++) d = b[f], c = d.selector + " ", void 0 === e[c] && (e[c] = d.needsContext ? n(c, this).index(i) >= 0 : n.find(c, this, null, [i]).length), e[c] && e.push(d);
                            e.length && g.push({
                                elem: i,
                                handlers: e
                            })
                        }
                return h < b.length && g.push({
                    elem: this,
                    handlers: b.slice(h)
                }), g
            },
            fix: function(a) {
                if (a[n.expando]) return a;
                var b, c, d, e = a.type,
                    f = a,
                    g = this.fixHooks[e];
                g || (this.fixHooks[e] = g = $.test(e) ? this.mouseHooks : Z.test(e) ? this.keyHooks : {}), d = g.props ? this.props.concat(g.props) : this.props, a = new n.Event(f), b = d.length;
                while (b--) c = d[b], a[c] = f[c];
                return a.target || (a.target = f.srcElement || z), 3 === a.target.nodeType && (a.target = a.target.parentNode), a.metaKey = !!a.metaKey, g.filter ? g.filter(a, f) : a
            },
            props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
            fixHooks: {},
            keyHooks: {
                props: "char charCode key keyCode".split(" "),
                filter: function(a, b) {
                    return null == a.which && (a.which = null != b.charCode ? b.charCode : b.keyCode), a
                }
            },
            mouseHooks: {
                props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
                filter: function(a, b) {
                    var c, d, e, f = b.button,
                        g = b.fromElement;
                    return null == a.pageX && null != b.clientX && (d = a.target.ownerDocument || z, e = d.documentElement, c = d.body, a.pageX = b.clientX + (e && e.scrollLeft || c && c.scrollLeft || 0) - (e && e.clientLeft || c && c.clientLeft || 0), a.pageY = b.clientY + (e && e.scrollTop || c && c.scrollTop || 0) - (e && e.clientTop || c && c.clientTop || 0)), !a.relatedTarget && g && (a.relatedTarget = g === a.target ? b.toElement : g), a.which || void 0 === f || (a.which = 1 & f ? 1 : 2 & f ? 3 : 4 & f ? 2 : 0), a
                }
            },
            special: {
                load: {
                    noBubble: !0
                },
                focus: {
                    trigger: function() {
                        if (this !== db() && this.focus) try {
                            return this.focus(), !1
                        } catch (a) {}
                    },
                    delegateType: "focusin"
                },
                blur: {
                    trigger: function() {
                        return this === db() && this.blur ? (this.blur(), !1) : void 0
                    },
                    delegateType: "focusout"
                },
                click: {
                    trigger: function() {
                        return n.nodeName(this, "input") && "checkbox" === this.type && this.click ? (this.click(), !1) : void 0
                    },
                    _default: function(a) {
                        return n.nodeName(a.target, "a")
                    }
                },
                beforeunload: {
                    postDispatch: function(a) {
                        void 0 !== a.result && (a.originalEvent.returnValue = a.result)
                    }
                }
            },
            simulate: function(a, b, c, d) {
                var e = n.extend(new n.Event, c, {
                    type: a,
                    isSimulated: !0,
                    originalEvent: {}
                });
                d ? n.event.trigger(e, null, b) : n.event.dispatch.call(b, e), e.isDefaultPrevented() && c.preventDefault()
            }
        }, n.removeEvent = z.removeEventListener ? function(a, b, c) {
            a.removeEventListener && a.removeEventListener(b, c, !1)
        } : function(a, b, c) {
            var d = "on" + b;
            a.detachEvent && (typeof a[d] === L && (a[d] = null), a.detachEvent(d, c))
        }, n.Event = function(a, b) {
            return this instanceof n.Event ? (a && a.type ? (this.originalEvent = a, this.type = a.type, this.isDefaultPrevented = a.defaultPrevented || void 0 === a.defaultPrevented && (a.returnValue === !1 || a.getPreventDefault && a.getPreventDefault()) ? bb : cb) : this.type = a, b && n.extend(this, b), this.timeStamp = a && a.timeStamp || n.now(), void(this[n.expando] = !0)) : new n.Event(a, b)
        }, n.Event.prototype = {
            isDefaultPrevented: cb,
            isPropagationStopped: cb,
            isImmediatePropagationStopped: cb,
            preventDefault: function() {
                var a = this.originalEvent;
                this.isDefaultPrevented = bb, a && (a.preventDefault ? a.preventDefault() : a.returnValue = !1)
            },
            stopPropagation: function() {
                var a = this.originalEvent;
                this.isPropagationStopped = bb, a && (a.stopPropagation && a.stopPropagation(), a.cancelBubble = !0)
            },
            stopImmediatePropagation: function() {
                this.isImmediatePropagationStopped = bb, this.stopPropagation()
            }
        }, n.each({
            mouseenter: "mouseover",
            mouseleave: "mouseout"
        }, function(a, b) {
            n.event.special[a] = {
                delegateType: b,
                bindType: b,
                handle: function(a) {
                    var c, d = this,
                        e = a.relatedTarget,
                        f = a.handleObj;
                    return (!e || e !== d && !n.contains(d, e)) && (a.type = f.origType, c = f.handler.apply(this, arguments), a.type = b), c
                }
            }
        }), l.submitBubbles || (n.event.special.submit = {
            setup: function() {
                return n.nodeName(this, "form") ? !1 : void n.event.add(this, "click._submit keypress._submit", function(a) {
                    var b = a.target,
                        c = n.nodeName(b, "input") || n.nodeName(b, "button") ? b.form : void 0;
                    c && !n._data(c, "submitBubbles") && (n.event.add(c, "submit._submit", function(a) {
                        a._submit_bubble = !0
                    }), n._data(c, "submitBubbles", !0))
                })
            },
            postDispatch: function(a) {
                a._submit_bubble && (delete a._submit_bubble, this.parentNode && !a.isTrigger && n.event.simulate("submit", this.parentNode, a, !0))
            },
            teardown: function() {
                return n.nodeName(this, "form") ? !1 : void n.event.remove(this, "._submit")
            }
        }), l.changeBubbles || (n.event.special.change = {
            setup: function() {
                return Y.test(this.nodeName) ? (("checkbox" === this.type || "radio" === this.type) && (n.event.add(this, "propertychange._change", function(a) {
                    "checked" === a.originalEvent.propertyName && (this._just_changed = !0)
                }), n.event.add(this, "click._change", function(a) {
                    this._just_changed && !a.isTrigger && (this._just_changed = !1), n.event.simulate("change", this, a, !0)
                })), !1) : void n.event.add(this, "beforeactivate._change", function(a) {
                    var b = a.target;
                    Y.test(b.nodeName) && !n._data(b, "changeBubbles") && (n.event.add(b, "change._change", function(a) {
                        !this.parentNode || a.isSimulated || a.isTrigger || n.event.simulate("change", this.parentNode, a, !0)
                    }), n._data(b, "changeBubbles", !0))
                })
            },
            handle: function(a) {
                var b = a.target;
                return this !== b || a.isSimulated || a.isTrigger || "radio" !== b.type && "checkbox" !== b.type ? a.handleObj.handler.apply(this, arguments) : void 0
            },
            teardown: function() {
                return n.event.remove(this, "._change"), !Y.test(this.nodeName)
            }
        }), l.focusinBubbles || n.each({
            focus: "focusin",
            blur: "focusout"
        }, function(a, b) {
            var c = function(a) {
                n.event.simulate(b, a.target, n.event.fix(a), !0)
            };
            n.event.special[b] = {
                setup: function() {
                    var d = this.ownerDocument || this,
                        e = n._data(d, b);
                    e || d.addEventListener(a, c, !0), n._data(d, b, (e || 0) + 1)
                },
                teardown: function() {
                    var d = this.ownerDocument || this,
                        e = n._data(d, b) - 1;
                    e ? n._data(d, b, e) : (d.removeEventListener(a, c, !0), n._removeData(d, b))
                }
            }
        }), n.fn.extend({
            on: function(a, b, c, d, e) {
                var f, g;
                if ("object" == typeof a) {
                    "string" != typeof b && (c = c || b, b = void 0);
                    for (f in a) this.on(f, b, c, a[f], e);
                    return this
                }
                if (null == c && null == d ? (d = b, c = b = void 0) : null == d && ("string" == typeof b ? (d = c, c = void 0) : (d = c, c = b, b = void 0)), d === !1) d = cb;
                else if (!d) return this;
                return 1 === e && (g = d, d = function(a) {
                    return n().off(a), g.apply(this, arguments)
                }, d.guid = g.guid || (g.guid = n.guid++)), this.each(function() {
                    n.event.add(this, a, d, c, b)
                })
            },
            one: function(a, b, c, d) {
                return this.on(a, b, c, d, 1)
            },
            off: function(a, b, c) {
                var d, e;
                if (a && a.preventDefault && a.handleObj) return d = a.handleObj, n(a.delegateTarget).off(d.namespace ? d.origType + "." + d.namespace : d.origType, d.selector, d.handler), this;
                if ("object" == typeof a) {
                    for (e in a) this.off(e, b, a[e]);
                    return this
                }
                return (b === !1 || "function" == typeof b) && (c = b, b = void 0), c === !1 && (c = cb), this.each(function() {
                    n.event.remove(this, a, c, b)
                })
            },
            trigger: function(a, b) {
                return this.each(function() {
                    n.event.trigger(a, b, this)
                })
            },
            triggerHandler: function(a, b) {
                var c = this[0];
                return c ? n.event.trigger(a, b, c, !0) : void 0
            }
        });
    
        function eb(a) {
            var b = fb.split("|"),
                c = a.createDocumentFragment();
            if (c.createElement)
                while (b.length) c.createElement(b.pop());
            return c
        }
        var fb = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
            gb = / jQuery\d+="(?:null|\d+)"/g,
            hb = new RegExp("<(?:" + fb + ")[\\s/>]", "i"),
            ib = /^\s+/,
            jb = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
            kb = /<([\w:]+)/,
            lb = /<tbody/i,
            mb = /<|&#?\w+;/,
            nb = /<(?:script|style|link)/i,
            ob = /checked\s*(?:[^=]|=\s*.checked.)/i,
            pb = /^$|\/(?:java|ecma)script/i,
            qb = /^true\/(.*)/,
            rb = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
            sb = {
                option: [1, "<select multiple='multiple'>", "</select>"],
                legend: [1, "<fieldset>", "</fieldset>"],
                area: [1, "<map>", "</map>"],
                param: [1, "<object>", "</object>"],
                thead: [1, "<table>", "</table>"],
                tr: [2, "<table><tbody>", "</tbody></table>"],
                col: [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"],
                td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
                _default: l.htmlSerialize ? [0, "", ""] : [1, "X<div>", "</div>"]
            },
            tb = eb(z),
            ub = tb.appendChild(z.createElement("div"));
        sb.optgroup = sb.option, sb.tbody = sb.tfoot = sb.colgroup = sb.caption = sb.thead, sb.th = sb.td;
    
        function vb(a, b) {
            var c, d, e = 0,
                f = typeof a.getElementsByTagName !== L ? a.getElementsByTagName(b || "*") : typeof a.querySelectorAll !== L ? a.querySelectorAll(b || "*") : void 0;
            if (!f)
                for (f = [], c = a.childNodes || a; null != (d = c[e]); e++) !b || n.nodeName(d, b) ? f.push(d) : n.merge(f, vb(d, b));
            return void 0 === b || b && n.nodeName(a, b) ? n.merge([a], f) : f
        }
    
        function wb(a) {
            X.test(a.type) && (a.defaultChecked = a.checked)
        }
    
        function xb(a, b) {
            return n.nodeName(a, "table") && n.nodeName(11 !== b.nodeType ? b : b.firstChild, "tr") ? a.getElementsByTagName("tbody")[0] || a.appendChild(a.ownerDocument.createElement("tbody")) : a
        }
    
        function yb(a) {
            return a.type = (null !== n.find.attr(a, "type")) + "/" + a.type, a
        }
    
        function zb(a) {
            var b = qb.exec(a.type);
            return b ? a.type = b[1] : a.removeAttribute("type"), a
        }
    
        function Ab(a, b) {
            for (var c, d = 0; null != (c = a[d]); d++) n._data(c, "globalEval", !b || n._data(b[d], "globalEval"))
        }
    
        function Bb(a, b) {
            if (1 === b.nodeType && n.hasData(a)) {
                var c, d, e, f = n._data(a),
                    g = n._data(b, f),
                    h = f.events;
                if (h) {
                    delete g.handle, g.events = {};
                    for (c in h)
                        for (d = 0, e = h[c].length; e > d; d++) n.event.add(b, c, h[c][d])
                }
                g.data && (g.data = n.extend({}, g.data))
            }
        }
    
        function Cb(a, b) {
            var c, d, e;
            if (1 === b.nodeType) {
                if (c = b.nodeName.toLowerCase(), !l.noCloneEvent && b[n.expando]) {
                    e = n._data(b);
                    for (d in e.events) n.removeEvent(b, d, e.handle);
                    b.removeAttribute(n.expando)
                }
                "script" === c && b.text !== a.text ? (yb(b).text = a.text, zb(b)) : "object" === c ? (b.parentNode && (b.outerHTML = a.outerHTML), l.html5Clone && a.innerHTML && !n.trim(b.innerHTML) && (b.innerHTML = a.innerHTML)) : "input" === c && X.test(a.type) ? (b.defaultChecked = b.checked = a.checked, b.value !== a.value && (b.value = a.value)) : "option" === c ? b.defaultSelected = b.selected = a.defaultSelected : ("input" === c || "textarea" === c) && (b.defaultValue = a.defaultValue)
            }
        }
        n.extend({
            clone: function(a, b, c) {
                var d, e, f, g, h, i = n.contains(a.ownerDocument, a);
                if (l.html5Clone || n.isXMLDoc(a) || !hb.test("<" + a.nodeName + ">") ? f = a.cloneNode(!0) : (ub.innerHTML = a.outerHTML, ub.removeChild(f = ub.firstChild)), !(l.noCloneEvent && l.noCloneChecked || 1 !== a.nodeType && 11 !== a.nodeType || n.isXMLDoc(a)))
                    for (d = vb(f), h = vb(a), g = 0; null != (e = h[g]); ++g) d[g] && Cb(e, d[g]);
                if (b)
                    if (c)
                        for (h = h || vb(a), d = d || vb(f), g = 0; null != (e = h[g]); g++) Bb(e, d[g]);
                    else Bb(a, f);
                return d = vb(f, "script"), d.length > 0 && Ab(d, !i && vb(a, "script")), d = h = e = null, f
            },
            buildFragment: function(a, b, c, d) {
                for (var e, f, g, h, i, j, k, m = a.length, o = eb(b), p = [], q = 0; m > q; q++)
                    if (f = a[q], f || 0 === f)
                        if ("object" === n.type(f)) n.merge(p, f.nodeType ? [f] : f);
                        else if (mb.test(f)) {
                    h = h || o.appendChild(b.createElement("div")), i = (kb.exec(f) || ["", ""])[1].toLowerCase(), k = sb[i] || sb._default, h.innerHTML = k[1] + f.replace(jb, "<$1></$2>") + k[2], e = k[0];
                    while (e--) h = h.lastChild;
                    if (!l.leadingWhitespace && ib.test(f) && p.push(b.createTextNode(ib.exec(f)[0])), !l.tbody) {
                        f = "table" !== i || lb.test(f) ? "<table>" !== k[1] || lb.test(f) ? 0 : h : h.firstChild, e = f && f.childNodes.length;
                        while (e--) n.nodeName(j = f.childNodes[e], "tbody") && !j.childNodes.length && f.removeChild(j)
                    }
                    n.merge(p, h.childNodes), h.textContent = "";
                    while (h.firstChild) h.removeChild(h.firstChild);
                    h = o.lastChild
                } else p.push(b.createTextNode(f));
                h && o.removeChild(h), l.appendChecked || n.grep(vb(p, "input"), wb), q = 0;
                while (f = p[q++])
                    if ((!d || -1 === n.inArray(f, d)) && (g = n.contains(f.ownerDocument, f), h = vb(o.appendChild(f), "script"), g && Ab(h), c)) {
                        e = 0;
                        while (f = h[e++]) pb.test(f.type || "") && c.push(f)
                    }
                return h = null, o
            },
            cleanData: function(a, b) {
                for (var d, e, f, g, h = 0, i = n.expando, j = n.cache, k = l.deleteExpando, m = n.event.special; null != (d = a[h]); h++)
                    if ((b || n.acceptData(d)) && (f = d[i], g = f && j[f])) {
                        if (g.events)
                            for (e in g.events) m[e] ? n.event.remove(d, e) : n.removeEvent(d, e, g.handle);
                        j[f] && (delete j[f], k ? delete d[i] : typeof d.removeAttribute !== L ? d.removeAttribute(i) : d[i] = null, c.push(f))
                    }
            }
        }), n.fn.extend({
            text: function(a) {
                return W(this, function(a) {
                    return void 0 === a ? n.text(this) : this.empty().append((this[0] && this[0].ownerDocument || z).createTextNode(a))
                }, null, a, arguments.length)
            },
            append: function() {
                return this.domManip(arguments, function(a) {
                    if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) {
                        var b = xb(this, a);
                        b.appendChild(a)
                    }
                })
            },
            prepend: function() {
                return this.domManip(arguments, function(a) {
                    if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) {
                        var b = xb(this, a);
                        b.insertBefore(a, b.firstChild)
                    }
                })
            },
            before: function() {
                return this.domManip(arguments, function(a) {
                    this.parentNode && this.parentNode.insertBefore(a, this)
                })
            },
            after: function() {
                return this.domManip(arguments, function(a) {
                    this.parentNode && this.parentNode.insertBefore(a, this.nextSibling)
                })
            },
            remove: function(a, b) {
                for (var c, d = a ? n.filter(a, this) : this, e = 0; null != (c = d[e]); e++) b || 1 !== c.nodeType || n.cleanData(vb(c)), c.parentNode && (b && n.contains(c.ownerDocument, c) && Ab(vb(c, "script")), c.parentNode.removeChild(c));
                return this
            },
            empty: function() {
                for (var a, b = 0; null != (a = this[b]); b++) {
                    1 === a.nodeType && n.cleanData(vb(a, !1));
                    while (a.firstChild) a.removeChild(a.firstChild);
                    a.options && n.nodeName(a, "select") && (a.options.length = 0)
                }
                return this
            },
            clone: function(a, b) {
                return a = null == a ? !1 : a, b = null == b ? a : b, this.map(function() {
                    return n.clone(this, a, b)
                })
            },
            html: function(a) {
                return W(this, function(a) {
                    var b = this[0] || {},
                        c = 0,
                        d = this.length;
                    if (void 0 === a) return 1 === b.nodeType ? b.innerHTML.replace(gb, "") : void 0;
                    if (!("string" != typeof a || nb.test(a) || !l.htmlSerialize && hb.test(a) || !l.leadingWhitespace && ib.test(a) || sb[(kb.exec(a) || ["", ""])[1].toLowerCase()])) {
                        a = a.replace(jb, "<$1></$2>");
                        try {
                            for (; d > c; c++) b = this[c] || {}, 1 === b.nodeType && (n.cleanData(vb(b, !1)), b.innerHTML = a);
                            b = 0
                        } catch (e) {}
                    }
                    b && this.empty().append(a)
                }, null, a, arguments.length)
            },
            replaceWith: function() {
                var a = arguments[0];
                return this.domManip(arguments, function(b) {
                    a = this.parentNode, n.cleanData(vb(this)), a && a.replaceChild(b, this)
                }), a && (a.length || a.nodeType) ? this : this.remove()
            },
            detach: function(a) {
                return this.remove(a, !0)
            },
            domManip: function(a, b) {
                a = e.apply([], a);
                var c, d, f, g, h, i, j = 0,
                    k = this.length,
                    m = this,
                    o = k - 1,
                    p = a[0],
                    q = n.isFunction(p);
                if (q || k > 1 && "string" == typeof p && !l.checkClone && ob.test(p)) return this.each(function(c) {
                    var d = m.eq(c);
                    q && (a[0] = p.call(this, c, d.html())), d.domManip(a, b)
                });
                if (k && (i = n.buildFragment(a, this[0].ownerDocument, !1, this), c = i.firstChild, 1 === i.childNodes.length && (i = c), c)) {
                    for (g = n.map(vb(i, "script"), yb), f = g.length; k > j; j++) d = i, j !== o && (d = n.clone(d, !0, !0), f && n.merge(g, vb(d, "script"))), b.call(this[j], d, j);
                    if (f)
                        for (h = g[g.length - 1].ownerDocument, n.map(g, zb), j = 0; f > j; j++) d = g[j], pb.test(d.type || "") && !n._data(d, "globalEval") && n.contains(h, d) && (d.src ? n._evalUrl && n._evalUrl(d.src) : n.globalEval((d.text || d.textContent || d.innerHTML || "").replace(rb, "")));
                    i = c = null
                }
                return this
            }
        }), n.each({
            appendTo: "append",
            prependTo: "prepend",
            insertBefore: "before",
            insertAfter: "after",
            replaceAll: "replaceWith"
        }, function(a, b) {
            n.fn[a] = function(a) {
                for (var c, d = 0, e = [], g = n(a), h = g.length - 1; h >= d; d++) c = d === h ? this : this.clone(!0), n(g[d])[b](c), f.apply(e, c.get());
                return this.pushStack(e)
            }
        });
        var Db, Eb = {};
    
        function Fb(b, c) {
            var d = n(c.createElement(b)).appendTo(c.body),
                e = a.getDefaultComputedStyle ? a.getDefaultComputedStyle(d[0]).display : n.css(d[0], "display");
            return d.detach(), e
        }
    
        function Gb(a) {
            var b = z,
                c = Eb[a];
            return c || (c = Fb(a, b), "none" !== c && c || (Db = (Db || n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement), b = (Db[0].contentWindow || Db[0].contentDocument).document, b.write(), b.close(), c = Fb(a, b), Db.detach()), Eb[a] = c), c
        }! function() {
            var a, b, c = z.createElement("div"),
                d = "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";
            c.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>", a = c.getElementsByTagName("a")[0], a.style.cssText = "float:left;opacity:.5", l.opacity = /^0.5/.test(a.style.opacity), l.cssFloat = !!a.style.cssFloat, c.style.backgroundClip = "content-box", c.cloneNode(!0).style.backgroundClip = "", l.clearCloneStyle = "content-box" === c.style.backgroundClip, a = c = null, l.shrinkWrapBlocks = function() {
                var a, c, e, f;
                if (null == b) {
                    if (a = z.getElementsByTagName("body")[0], !a) return;
                    f = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px", c = z.createElement("div"), e = z.createElement("div"), a.appendChild(c).appendChild(e), b = !1, typeof e.style.zoom !== L && (e.style.cssText = d + ";width:1px;padding:1px;zoom:1", e.innerHTML = "<div></div>", e.firstChild.style.width = "5px", b = 3 !== e.offsetWidth), a.removeChild(c), a = c = e = null
                }
                return b
            }
        }();
        var Hb = /^margin/,
            Ib = new RegExp("^(" + T + ")(?!px)[a-z%]+$", "i"),
            Jb, Kb, Lb = /^(top|right|bottom|left)$/;
        a.getComputedStyle ? (Jb = function(a) {
            return a.ownerDocument.defaultView.getComputedStyle(a, null)
        }, Kb = function(a, b, c) {
            var d, e, f, g, h = a.style;
            return c = c || Jb(a), g = c ? c.getPropertyValue(b) || c[b] : void 0, c && ("" !== g || n.contains(a.ownerDocument, a) || (g = n.style(a, b)), Ib.test(g) && Hb.test(b) && (d = h.width, e = h.minWidth, f = h.maxWidth, h.minWidth = h.maxWidth = h.width = g, g = c.width, h.width = d, h.minWidth = e, h.maxWidth = f)), void 0 === g ? g : g + ""
        }) : z.documentElement.currentStyle && (Jb = function(a) {
            return a.currentStyle
        }, Kb = function(a, b, c) {
            var d, e, f, g, h = a.style;
            return c = c || Jb(a), g = c ? c[b] : void 0, null == g && h && h[b] && (g = h[b]), Ib.test(g) && !Lb.test(b) && (d = h.left, e = a.runtimeStyle, f = e && e.left, f && (e.left = a.currentStyle.left), h.left = "fontSize" === b ? "1em" : g, g = h.pixelLeft + "px", h.left = d, f && (e.left = f)), void 0 === g ? g : g + "" || "auto"
        });
    
        function Mb(a, b) {
            return {
                get: function() {
                    var c = a();
                    if (null != c) return c ? void delete this.get : (this.get = b).apply(this, arguments)
                }
            }
        }! function() {
            var b, c, d, e, f, g, h = z.createElement("div"),
                i = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px",
                j = "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";
            h.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>", b = h.getElementsByTagName("a")[0], b.style.cssText = "float:left;opacity:.5", l.opacity = /^0.5/.test(b.style.opacity), l.cssFloat = !!b.style.cssFloat, h.style.backgroundClip = "content-box", h.cloneNode(!0).style.backgroundClip = "", l.clearCloneStyle = "content-box" === h.style.backgroundClip, b = h = null, n.extend(l, {
                reliableHiddenOffsets: function() {
                    if (null != c) return c;
                    var a, b, d, e = z.createElement("div"),
                        f = z.getElementsByTagName("body")[0];
                    if (f) return e.setAttribute("className", "t"), e.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>", a = z.createElement("div"), a.style.cssText = i, f.appendChild(a).appendChild(e), e.innerHTML = "<table><tr><td></td><td>t</td></tr></table>", b = e.getElementsByTagName("td"), b[0].style.cssText = "padding:0;margin:0;border:0;display:none", d = 0 === b[0].offsetHeight, b[0].style.display = "", b[1].style.display = "none", c = d && 0 === b[0].offsetHeight, f.removeChild(a), e = f = null, c
                },
                boxSizing: function() {
                    return null == d && k(), d
                },
                boxSizingReliable: function() {
                    return null == e && k(), e
                },
                pixelPosition: function() {
                    return null == f && k(), f
                },
                reliableMarginRight: function() {
                    var b, c, d, e;
                    if (null == g && a.getComputedStyle) {
                        if (b = z.getElementsByTagName("body")[0], !b) return;
                        c = z.createElement("div"), d = z.createElement("div"), c.style.cssText = i, b.appendChild(c).appendChild(d), e = d.appendChild(z.createElement("div")), e.style.cssText = d.style.cssText = j, e.style.marginRight = e.style.width = "0", d.style.width = "1px", g = !parseFloat((a.getComputedStyle(e, null) || {}).marginRight), b.removeChild(c)
                    }
                    return g
                }
            });
    
            function k() {
                var b, c, h = z.getElementsByTagName("body")[0];
                h && (b = z.createElement("div"), c = z.createElement("div"), b.style.cssText = i, h.appendChild(b).appendChild(c), c.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;display:block;padding:1px;border:1px;width:4px;margin-top:1%;top:1%", n.swap(h, null != h.style.zoom ? {
                    zoom: 1
                } : {}, function() {
                    d = 4 === c.offsetWidth
                }), e = !0, f = !1, g = !0, a.getComputedStyle && (f = "1%" !== (a.getComputedStyle(c, null) || {}).top, e = "4px" === (a.getComputedStyle(c, null) || {
                    width: "4px"
                }).width), h.removeChild(b), c = h = null)
            }
        }(), n.swap = function(a, b, c, d) {
            var e, f, g = {};
            for (f in b) g[f] = a.style[f], a.style[f] = b[f];
            e = c.apply(a, d || []);
            for (f in b) a.style[f] = g[f];
            return e
        };
        var Nb = /alpha\([^)]*\)/i,
            Ob = /opacity\s*=\s*([^)]*)/,
            Pb = /^(none|table(?!-c[ea]).+)/,
            Qb = new RegExp("^(" + T + ")(.*)$", "i"),
            Rb = new RegExp("^([+-])=(" + T + ")", "i"),
            Sb = {
                position: "absolute",
                visibility: "hidden",
                display: "block"
            },
            Tb = {
                letterSpacing: 0,
                fontWeight: 400
            },
            Ub = ["Webkit", "O", "Moz", "ms"];
    
        function Vb(a, b) {
            if (b in a) return b;
            var c = b.charAt(0).toUpperCase() + b.slice(1),
                d = b,
                e = Ub.length;
            while (e--)
                if (b = Ub[e] + c, b in a) return b;
            return d
        }
    
        function Wb(a, b) {
            for (var c, d, e, f = [], g = 0, h = a.length; h > g; g++) d = a[g], d.style && (f[g] = n._data(d, "olddisplay"), c = d.style.display, b ? (f[g] || "none" !== c || (d.style.display = ""), "" === d.style.display && V(d) && (f[g] = n._data(d, "olddisplay", Gb(d.nodeName)))) : f[g] || (e = V(d), (c && "none" !== c || !e) && n._data(d, "olddisplay", e ? c : n.css(d, "display"))));
            for (g = 0; h > g; g++) d = a[g], d.style && (b && "none" !== d.style.display && "" !== d.style.display || (d.style.display = b ? f[g] || "" : "none"));
            return a
        }
    
        function Xb(a, b, c) {
            var d = Qb.exec(b);
            return d ? Math.max(0, d[1] - (c || 0)) + (d[2] || "px") : b
        }
    
        function Yb(a, b, c, d, e) {
            for (var f = c === (d ? "border" : "content") ? 4 : "width" === b ? 1 : 0, g = 0; 4 > f; f += 2) "margin" === c && (g += n.css(a, c + U[f], !0, e)), d ? ("content" === c && (g -= n.css(a, "padding" + U[f], !0, e)), "margin" !== c && (g -= n.css(a, "border" + U[f] + "Width", !0, e))) : (g += n.css(a, "padding" + U[f], !0, e), "padding" !== c && (g += n.css(a, "border" + U[f] + "Width", !0, e)));
            return g
        }
    
        function Zb(a, b, c) {
            var d = !0,
                e = "width" === b ? a.offsetWidth : a.offsetHeight,
                f = Jb(a),
                g = l.boxSizing() && "border-box" === n.css(a, "boxSizing", !1, f);
            if (0 >= e || null == e) {
                if (e = Kb(a, b, f), (0 > e || null == e) && (e = a.style[b]), Ib.test(e)) return e;
                d = g && (l.boxSizingReliable() || e === a.style[b]), e = parseFloat(e) || 0
            }
            return e + Yb(a, b, c || (g ? "border" : "content"), d, f) + "px"
        }
        n.extend({
            cssHooks: {
                opacity: {
                    get: function(a, b) {
                        if (b) {
                            var c = Kb(a, "opacity");
                            return "" === c ? "1" : c
                        }
                    }
                }
            },
            cssNumber: {
                columnCount: !0,
                fillOpacity: !0,
                fontWeight: !0,
                lineHeight: !0,
                opacity: !0,
                order: !0,
                orphans: !0,
                widows: !0,
                zIndex: !0,
                zoom: !0
            },
            cssProps: {
                "float": l.cssFloat ? "cssFloat" : "styleFloat"
            },
            style: function(a, b, c, d) {
                if (a && 3 !== a.nodeType && 8 !== a.nodeType && a.style) {
                    var e, f, g, h = n.camelCase(b),
                        i = a.style;
                    if (b = n.cssProps[h] || (n.cssProps[h] = Vb(i, h)), g = n.cssHooks[b] || n.cssHooks[h], void 0 === c) return g && "get" in g && void 0 !== (e = g.get(a, !1, d)) ? e : i[b];
                    if (f = typeof c, "string" === f && (e = Rb.exec(c)) && (c = (e[1] + 1) * e[2] + parseFloat(n.css(a, b)), f = "number"), null != c && c === c && ("number" !== f || n.cssNumber[h] || (c += "px"), l.clearCloneStyle || "" !== c || 0 !== b.indexOf("background") || (i[b] = "inherit"), !(g && "set" in g && void 0 === (c = g.set(a, c, d))))) try {
                        i[b] = "", i[b] = c
                    } catch (j) {}
                }
            },
            css: function(a, b, c, d) {
                var e, f, g, h = n.camelCase(b);
                return b = n.cssProps[h] || (n.cssProps[h] = Vb(a.style, h)), g = n.cssHooks[b] || n.cssHooks[h], g && "get" in g && (f = g.get(a, !0, c)), void 0 === f && (f = Kb(a, b, d)), "normal" === f && b in Tb && (f = Tb[b]), "" === c || c ? (e = parseFloat(f), c === !0 || n.isNumeric(e) ? e || 0 : f) : f
            }
        }), n.each(["height", "width"], function(a, b) {
            n.cssHooks[b] = {
                get: function(a, c, d) {
                    return c ? 0 === a.offsetWidth && Pb.test(n.css(a, "display")) ? n.swap(a, Sb, function() {
                        return Zb(a, b, d)
                    }) : Zb(a, b, d) : void 0
                },
                set: function(a, c, d) {
                    var e = d && Jb(a);
                    return Xb(a, c, d ? Yb(a, b, d, l.boxSizing() && "border-box" === n.css(a, "boxSizing", !1, e), e) : 0)
                }
            }
        }), l.opacity || (n.cssHooks.opacity = {
            get: function(a, b) {
                return Ob.test((b && a.currentStyle ? a.currentStyle.filter : a.style.filter) || "") ? .01 * parseFloat(RegExp.$1) + "" : b ? "1" : ""
            },
            set: function(a, b) {
                var c = a.style,
                    d = a.currentStyle,
                    e = n.isNumeric(b) ? "alpha(opacity=" + 100 * b + ")" : "",
                    f = d && d.filter || c.filter || "";
                c.zoom = 1, (b >= 1 || "" === b) && "" === n.trim(f.replace(Nb, "")) && c.removeAttribute && (c.removeAttribute("filter"), "" === b || d && !d.filter) || (c.filter = Nb.test(f) ? f.replace(Nb, e) : f + " " + e)
            }
        }), n.cssHooks.marginRight = Mb(l.reliableMarginRight, function(a, b) {
            return b ? n.swap(a, {
                display: "inline-block"
            }, Kb, [a, "marginRight"]) : void 0
        }), n.each({
            margin: "",
            padding: "",
            border: "Width"
        }, function(a, b) {
            n.cssHooks[a + b] = {
                expand: function(c) {
                    for (var d = 0, e = {}, f = "string" == typeof c ? c.split(" ") : [c]; 4 > d; d++) e[a + U[d] + b] = f[d] || f[d - 2] || f[0];
                    return e
                }
            }, Hb.test(a) || (n.cssHooks[a + b].set = Xb)
        }), n.fn.extend({
            css: function(a, b) {
                return W(this, function(a, b, c) {
                    var d, e, f = {},
                        g = 0;
                    if (n.isArray(b)) {
                        for (d = Jb(a), e = b.length; e > g; g++) f[b[g]] = n.css(a, b[g], !1, d);
                        return f
                    }
                    return void 0 !== c ? n.style(a, b, c) : n.css(a, b)
                }, a, b, arguments.length > 1)
            },
            show: function() {
                return Wb(this, !0)
            },
            hide: function() {
                return Wb(this)
            },
            toggle: function(a) {
                return "boolean" == typeof a ? a ? this.show() : this.hide() : this.each(function() {
                    V(this) ? n(this).show() : n(this).hide()
                })
            }
        });
    
        function $b(a, b, c, d, e) {
            return new $b.prototype.init(a, b, c, d, e)
        }
        n.Tween = $b, $b.prototype = {
            constructor: $b,
            init: function(a, b, c, d, e, f) {
                this.elem = a, this.prop = c, this.easing = e || "swing", this.options = b, this.start = this.now = this.cur(), this.end = d, this.unit = f || (n.cssNumber[c] ? "" : "px")
            },
            cur: function() {
                var a = $b.propHooks[this.prop];
                return a && a.get ? a.get(this) : $b.propHooks._default.get(this)
            },
            run: function(a) {
                var b, c = $b.propHooks[this.prop];
                return this.pos = b = this.options.duration ? n.easing[this.easing](a, this.options.duration * a, 0, 1, this.options.duration) : a, this.now = (this.end - this.start) * b + this.start, this.options.step && this.options.step.call(this.elem, this.now, this), c && c.set ? c.set(this) : $b.propHooks._default.set(this), this
            }
        }, $b.prototype.init.prototype = $b.prototype, $b.propHooks = {
            _default: {
                get: function(a) {
                    var b;
                    return null == a.elem[a.prop] || a.elem.style && null != a.elem.style[a.prop] ? (b = n.css(a.elem, a.prop, ""), b && "auto" !== b ? b : 0) : a.elem[a.prop]
                },
                set: function(a) {
                    n.fx.step[a.prop] ? n.fx.step[a.prop](a) : a.elem.style && (null != a.elem.style[n.cssProps[a.prop]] || n.cssHooks[a.prop]) ? n.style(a.elem, a.prop, a.now + a.unit) : a.elem[a.prop] = a.now
                }
            }
        }, $b.propHooks.scrollTop = $b.propHooks.scrollLeft = {
            set: function(a) {
                a.elem.nodeType && a.elem.parentNode && (a.elem[a.prop] = a.now)
            }
        }, n.easing = {
            linear: function(a) {
                return a
            },
            swing: function(a) {
                return .5 - Math.cos(a * Math.PI) / 2
            }
        }, n.fx = $b.prototype.init, n.fx.step = {};
        var _b, ac, bc = /^(?:toggle|show|hide)$/,
            cc = new RegExp("^(?:([+-])=|)(" + T + ")([a-z%]*)$", "i"),
            dc = /queueHooks$/,
            ec = [jc],
            fc = {
                "*": [function(a, b) {
                    var c = this.createTween(a, b),
                        d = c.cur(),
                        e = cc.exec(b),
                        f = e && e[3] || (n.cssNumber[a] ? "" : "px"),
                        g = (n.cssNumber[a] || "px" !== f && +d) && cc.exec(n.css(c.elem, a)),
                        h = 1,
                        i = 20;
                    if (g && g[3] !== f) {
                        f = f || g[3], e = e || [], g = +d || 1;
                        do h = h || ".5", g /= h, n.style(c.elem, a, g + f); while (h !== (h = c.cur() / d) && 1 !== h && --i)
                    }
                    return e && (g = c.start = +g || +d || 0, c.unit = f, c.end = e[1] ? g + (e[1] + 1) * e[2] : +e[2]), c
                }]
            };
    
        function gc() {
            return setTimeout(function() {
                _b = void 0
            }), _b = n.now()
        }
    
        function hc(a, b) {
            var c, d = {
                    height: a
                },
                e = 0;
            for (b = b ? 1 : 0; 4 > e; e += 2 - b) c = U[e], d["margin" + c] = d["padding" + c] = a;
            return b && (d.opacity = d.width = a), d
        }
    
        function ic(a, b, c) {
            for (var d, e = (fc[b] || []).concat(fc["*"]), f = 0, g = e.length; g > f; f++)
                if (d = e[f].call(c, b, a)) return d
        }
    
        function jc(a, b, c) {
            var d, e, f, g, h, i, j, k, m = this,
                o = {},
                p = a.style,
                q = a.nodeType && V(a),
                r = n._data(a, "fxshow");
            c.queue || (h = n._queueHooks(a, "fx"), null == h.unqueued && (h.unqueued = 0, i = h.empty.fire, h.empty.fire = function() {
                h.unqueued || i()
            }), h.unqueued++, m.always(function() {
                m.always(function() {
                    h.unqueued--, n.queue(a, "fx").length || h.empty.fire()
                })
            })), 1 === a.nodeType && ("height" in b || "width" in b) && (c.overflow = [p.overflow, p.overflowX, p.overflowY], j = n.css(a, "display"), k = Gb(a.nodeName), "none" === j && (j = k), "inline" === j && "none" === n.css(a, "float") && (l.inlineBlockNeedsLayout && "inline" !== k ? p.zoom = 1 : p.display = "inline-block")), c.overflow && (p.overflow = "hidden", l.shrinkWrapBlocks() || m.always(function() {
                p.overflow = c.overflow[0], p.overflowX = c.overflow[1], p.overflowY = c.overflow[2]
            }));
            for (d in b)
                if (e = b[d], bc.exec(e)) {
                    if (delete b[d], f = f || "toggle" === e, e === (q ? "hide" : "show")) {
                        if ("show" !== e || !r || void 0 === r[d]) continue;
                        q = !0
                    }
                    o[d] = r && r[d] || n.style(a, d)
                }
            if (!n.isEmptyObject(o)) {
                r ? "hidden" in r && (q = r.hidden) : r = n._data(a, "fxshow", {}), f && (r.hidden = !q), q ? n(a).show() : m.done(function() {
                    n(a).hide()
                }), m.done(function() {
                    var b;
                    n._removeData(a, "fxshow");
                    for (b in o) n.style(a, b, o[b])
                });
                for (d in o) g = ic(q ? r[d] : 0, d, m), d in r || (r[d] = g.start, q && (g.end = g.start, g.start = "width" === d || "height" === d ? 1 : 0))
            }
        }
    
        function kc(a, b) {
            var c, d, e, f, g;
            for (c in a)
                if (d = n.camelCase(c), e = b[d], f = a[c], n.isArray(f) && (e = f[1], f = a[c] = f[0]), c !== d && (a[d] = f, delete a[c]), g = n.cssHooks[d], g && "expand" in g) {
                    f = g.expand(f), delete a[d];
                    for (c in f) c in a || (a[c] = f[c], b[c] = e)
                } else b[d] = e
        }
    
        function lc(a, b, c) {
            var d, e, f = 0,
                g = ec.length,
                h = n.Deferred().always(function() {
                    delete i.elem
                }),
                i = function() {
                    if (e) return !1;
                    for (var b = _b || gc(), c = Math.max(0, j.startTime + j.duration - b), d = c / j.duration || 0, f = 1 - d, g = 0, i = j.tweens.length; i > g; g++) j.tweens[g].run(f);
                    return h.notifyWith(a, [j, f, c]), 1 > f && i ? c : (h.resolveWith(a, [j]), !1)
                },
                j = h.promise({
                    elem: a,
                    props: n.extend({}, b),
                    opts: n.extend(!0, {
                        specialEasing: {}
                    }, c),
                    originalProperties: b,
                    originalOptions: c,
                    startTime: _b || gc(),
                    duration: c.duration,
                    tweens: [],
                    createTween: function(b, c) {
                        var d = n.Tween(a, j.opts, b, c, j.opts.specialEasing[b] || j.opts.easing);
                        return j.tweens.push(d), d
                    },
                    stop: function(b) {
                        var c = 0,
                            d = b ? j.tweens.length : 0;
                        if (e) return this;
                        for (e = !0; d > c; c++) j.tweens[c].run(1);
                        return b ? h.resolveWith(a, [j, b]) : h.rejectWith(a, [j, b]), this
                    }
                }),
                k = j.props;
            for (kc(k, j.opts.specialEasing); g > f; f++)
                if (d = ec[f].call(j, a, k, j.opts)) return d;
            return n.map(k, ic, j), n.isFunction(j.opts.start) && j.opts.start.call(a, j), n.fx.timer(n.extend(i, {
                elem: a,
                anim: j,
                queue: j.opts.queue
            })), j.progress(j.opts.progress).done(j.opts.done, j.opts.complete).fail(j.opts.fail).always(j.opts.always)
        }
        n.Animation = n.extend(lc, {
                tweener: function(a, b) {
                    n.isFunction(a) ? (b = a, a = ["*"]) : a = a.split(" ");
                    for (var c, d = 0, e = a.length; e > d; d++) c = a[d], fc[c] = fc[c] || [], fc[c].unshift(b)
                },
                prefilter: function(a, b) {
                    b ? ec.unshift(a) : ec.push(a)
                }
            }), n.speed = function(a, b, c) {
                var d = a && "object" == typeof a ? n.extend({}, a) : {
                    complete: c || !c && b || n.isFunction(a) && a,
                    duration: a,
                    easing: c && b || b && !n.isFunction(b) && b
                };
                return d.duration = n.fx.off ? 0 : "number" == typeof d.duration ? d.duration : d.duration in n.fx.speeds ? n.fx.speeds[d.duration] : n.fx.speeds._default, (null == d.queue || d.queue === !0) && (d.queue = "fx"), d.old = d.complete, d.complete = function() {
                    n.isFunction(d.old) && d.old.call(this), d.queue && n.dequeue(this, d.queue)
                }, d
            }, n.fn.extend({
                fadeTo: function(a, b, c, d) {
                    return this.filter(V).css("opacity", 0).show().end().animate({
                        opacity: b
                    }, a, c, d)
                },
                animate: function(a, b, c, d) {
                    var e = n.isEmptyObject(a),
                        f = n.speed(b, c, d),
                        g = function() {
                            var b = lc(this, n.extend({}, a), f);
                            (e || n._data(this, "finish")) && b.stop(!0)
                        };
                    return g.finish = g, e || f.queue === !1 ? this.each(g) : this.queue(f.queue, g)
                },
                stop: function(a, b, c) {
                    var d = function(a) {
                        var b = a.stop;
                        delete a.stop, b(c)
                    };
                    return "string" != typeof a && (c = b, b = a, a = void 0), b && a !== !1 && this.queue(a || "fx", []), this.each(function() {
                        var b = !0,
                            e = null != a && a + "queueHooks",
                            f = n.timers,
                            g = n._data(this);
                        if (e) g[e] && g[e].stop && d(g[e]);
                        else
                            for (e in g) g[e] && g[e].stop && dc.test(e) && d(g[e]);
                        for (e = f.length; e--;) f[e].elem !== this || null != a && f[e].queue !== a || (f[e].anim.stop(c), b = !1, f.splice(e, 1));
                        (b || !c) && n.dequeue(this, a)
                    })
                },
                finish: function(a) {
                    return a !== !1 && (a = a || "fx"), this.each(function() {
                        var b, c = n._data(this),
                            d = c[a + "queue"],
                            e = c[a + "queueHooks"],
                            f = n.timers,
                            g = d ? d.length : 0;
                        for (c.finish = !0, n.queue(this, a, []), e && e.stop && e.stop.call(this, !0), b = f.length; b--;) f[b].elem === this && f[b].queue === a && (f[b].anim.stop(!0), f.splice(b, 1));
                        for (b = 0; g > b; b++) d[b] && d[b].finish && d[b].finish.call(this);
                        delete c.finish
                    })
                }
            }), n.each(["toggle", "show", "hide"], function(a, b) {
                var c = n.fn[b];
                n.fn[b] = function(a, d, e) {
                    return null == a || "boolean" == typeof a ? c.apply(this, arguments) : this.animate(hc(b, !0), a, d, e)
                }
            }), n.each({
                slideDown: hc("show"),
                slideUp: hc("hide"),
                slideToggle: hc("toggle"),
                fadeIn: {
                    opacity: "show"
                },
                fadeOut: {
                    opacity: "hide"
                },
                fadeToggle: {
                    opacity: "toggle"
                }
            }, function(a, b) {
                n.fn[a] = function(a, c, d) {
                    return this.animate(b, a, c, d)
                }
            }), n.timers = [], n.fx.tick = function() {
                var a, b = n.timers,
                    c = 0;
                for (_b = n.now(); c < b.length; c++) a = b[c], a() || b[c] !== a || b.splice(c--, 1);
                b.length || n.fx.stop(), _b = void 0
            }, n.fx.timer = function(a) {
                n.timers.push(a), a() ? n.fx.start() : n.timers.pop()
            }, n.fx.interval = 13, n.fx.start = function() {
                ac || (ac = setInterval(n.fx.tick, n.fx.interval))
            }, n.fx.stop = function() {
                clearInterval(ac), ac = null
            }, n.fx.speeds = {
                slow: 600,
                fast: 200,
                _default: 400
            }, n.fn.delay = function(a, b) {
                return a = n.fx ? n.fx.speeds[a] || a : a, b = b || "fx", this.queue(b, function(b, c) {
                    var d = setTimeout(b, a);
                    c.stop = function() {
                        clearTimeout(d)
                    }
                })
            },
            function() {
                var a, b, c, d, e = z.createElement("div");
                e.setAttribute("className", "t"), e.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>", a = e.getElementsByTagName("a")[0], c = z.createElement("select"), d = c.appendChild(z.createElement("option")), b = e.getElementsByTagName("input")[0], a.style.cssText = "top:1px", l.getSetAttribute = "t" !== e.className, l.style = /top/.test(a.getAttribute("style")), l.hrefNormalized = "/a" === a.getAttribute("href"), l.checkOn = !!b.value, l.optSelected = d.selected, l.enctype = !!z.createElement("form").enctype, c.disabled = !0, l.optDisabled = !d.disabled, b = z.createElement("input"), b.setAttribute("value", ""), l.input = "" === b.getAttribute("value"), b.value = "t", b.setAttribute("type", "radio"), l.radioValue = "t" === b.value, a = b = c = d = e = null
            }();
        var mc = /\r/g;
        n.fn.extend({
            val: function(a) {
                var b, c, d, e = this[0]; {
                    if (arguments.length) return d = n.isFunction(a), this.each(function(c) {
                        var e;
                        1 === this.nodeType && (e = d ? a.call(this, c, n(this).val()) : a, null == e ? e = "" : "number" == typeof e ? e += "" : n.isArray(e) && (e = n.map(e, function(a) {
                            return null == a ? "" : a + ""
                        })), b = n.valHooks[this.type] || n.valHooks[this.nodeName.toLowerCase()], b && "set" in b && void 0 !== b.set(this, e, "value") || (this.value = e))
                    });
                    if (e) return b = n.valHooks[e.type] || n.valHooks[e.nodeName.toLowerCase()], b && "get" in b && void 0 !== (c = b.get(e, "value")) ? c : (c = e.value, "string" == typeof c ? c.replace(mc, "") : null == c ? "" : c)
                }
            }
        }), n.extend({
            valHooks: {
                option: {
                    get: function(a) {
                        var b = n.find.attr(a, "value");
                        return null != b ? b : n.text(a)
                    }
                },
                select: {
                    get: function(a) {
                        for (var b, c, d = a.options, e = a.selectedIndex, f = "select-one" === a.type || 0 > e, g = f ? null : [], h = f ? e + 1 : d.length, i = 0 > e ? h : f ? e : 0; h > i; i++)
                            if (c = d[i], !(!c.selected && i !== e || (l.optDisabled ? c.disabled : null !== c.getAttribute("disabled")) || c.parentNode.disabled && n.nodeName(c.parentNode, "optgroup"))) {
                                if (b = n(c).val(), f) return b;
                                g.push(b)
                            }
                        return g
                    },
                    set: function(a, b) {
                        var c, d, e = a.options,
                            f = n.makeArray(b),
                            g = e.length;
                        while (g--)
                            if (d = e[g], n.inArray(n.valHooks.option.get(d), f) >= 0) try {
                                d.selected = c = !0
                            } catch (h) {
                                d.scrollHeight
                            } else d.selected = !1;
                        return c || (a.selectedIndex = -1), e
                    }
                }
            }
        }), n.each(["radio", "checkbox"], function() {
            n.valHooks[this] = {
                set: function(a, b) {
                    return n.isArray(b) ? a.checked = n.inArray(n(a).val(), b) >= 0 : void 0
                }
            }, l.checkOn || (n.valHooks[this].get = function(a) {
                return null === a.getAttribute("value") ? "on" : a.value
            })
        });
        var nc, oc, pc = n.expr.attrHandle,
            qc = /^(?:checked|selected)$/i,
            rc = l.getSetAttribute,
            sc = l.input;
        n.fn.extend({
            attr: function(a, b) {
                return W(this, n.attr, a, b, arguments.length > 1)
            },
            removeAttr: function(a) {
                return this.each(function() {
                    n.removeAttr(this, a)
                })
            }
        }), n.extend({
            attr: function(a, b, c) {
                var d, e, f = a.nodeType;
                if (a && 3 !== f && 8 !== f && 2 !== f) return typeof a.getAttribute === L ? n.prop(a, b, c) : (1 === f && n.isXMLDoc(a) || (b = b.toLowerCase(), d = n.attrHooks[b] || (n.expr.match.bool.test(b) ? oc : nc)), void 0 === c ? d && "get" in d && null !== (e = d.get(a, b)) ? e : (e = n.find.attr(a, b), null == e ? void 0 : e) : null !== c ? d && "set" in d && void 0 !== (e = d.set(a, c, b)) ? e : (a.setAttribute(b, c + ""), c) : void n.removeAttr(a, b))
            },
            removeAttr: function(a, b) {
                var c, d, e = 0,
                    f = b && b.match(F);
                if (f && 1 === a.nodeType)
                    while (c = f[e++]) d = n.propFix[c] || c, n.expr.match.bool.test(c) ? sc && rc || !qc.test(c) ? a[d] = !1 : a[n.camelCase("default-" + c)] = a[d] = !1 : n.attr(a, c, ""), a.removeAttribute(rc ? c : d)
            },
            attrHooks: {
                type: {
                    set: function(a, b) {
                        if (!l.radioValue && "radio" === b && n.nodeName(a, "input")) {
                            var c = a.value;
                            return a.setAttribute("type", b), c && (a.value = c), b
                        }
                    }
                }
            }
        }), oc = {
            set: function(a, b, c) {
                return b === !1 ? n.removeAttr(a, c) : sc && rc || !qc.test(c) ? a.setAttribute(!rc && n.propFix[c] || c, c) : a[n.camelCase("default-" + c)] = a[c] = !0, c
            }
        }, n.each(n.expr.match.bool.source.match(/\w+/g), function(a, b) {
            var c = pc[b] || n.find.attr;
            pc[b] = sc && rc || !qc.test(b) ? function(a, b, d) {
                var e, f;
                return d || (f = pc[b], pc[b] = e, e = null != c(a, b, d) ? b.toLowerCase() : null, pc[b] = f), e
            } : function(a, b, c) {
                return c ? void 0 : a[n.camelCase("default-" + b)] ? b.toLowerCase() : null
            }
        }), sc && rc || (n.attrHooks.value = {
            set: function(a, b, c) {
                return n.nodeName(a, "input") ? void(a.defaultValue = b) : nc && nc.set(a, b, c)
            }
        }), rc || (nc = {
            set: function(a, b, c) {
                var d = a.getAttributeNode(c);
                return d || a.setAttributeNode(d = a.ownerDocument.createAttribute(c)), d.value = b += "", "value" === c || b === a.getAttribute(c) ? b : void 0
            }
        }, pc.id = pc.name = pc.coords = function(a, b, c) {
            var d;
            return c ? void 0 : (d = a.getAttributeNode(b)) && "" !== d.value ? d.value : null
        }, n.valHooks.button = {
            get: function(a, b) {
                var c = a.getAttributeNode(b);
                return c && c.specified ? c.value : void 0
            },
            set: nc.set
        }, n.attrHooks.contenteditable = {
            set: function(a, b, c) {
                nc.set(a, "" === b ? !1 : b, c)
            }
        }, n.each(["width", "height"], function(a, b) {
            n.attrHooks[b] = {
                set: function(a, c) {
                    return "" === c ? (a.setAttribute(b, "auto"), c) : void 0
                }
            }
        })), l.style || (n.attrHooks.style = {
            get: function(a) {
                return a.style.cssText || void 0
            },
            set: function(a, b) {
                return a.style.cssText = b + ""
            }
        });
        var tc = /^(?:input|select|textarea|button|object)$/i,
            uc = /^(?:a|area)$/i;
        n.fn.extend({
            prop: function(a, b) {
                return W(this, n.prop, a, b, arguments.length > 1)
            },
            removeProp: function(a) {
                return a = n.propFix[a] || a, this.each(function() {
                    try {
                        this[a] = void 0, delete this[a]
                    } catch (b) {}
                })
            }
        }), n.extend({
            propFix: {
                "for": "htmlFor",
                "class": "className"
            },
            prop: function(a, b, c) {
                var d, e, f, g = a.nodeType;
                if (a && 3 !== g && 8 !== g && 2 !== g) return f = 1 !== g || !n.isXMLDoc(a), f && (b = n.propFix[b] || b, e = n.propHooks[b]), void 0 !== c ? e && "set" in e && void 0 !== (d = e.set(a, c, b)) ? d : a[b] = c : e && "get" in e && null !== (d = e.get(a, b)) ? d : a[b]
            },
            propHooks: {
                tabIndex: {
                    get: function(a) {
                        var b = n.find.attr(a, "tabindex");
                        return b ? parseInt(b, 10) : tc.test(a.nodeName) || uc.test(a.nodeName) && a.href ? 0 : -1
                    }
                }
            }
        }), l.hrefNormalized || n.each(["href", "src"], function(a, b) {
            n.propHooks[b] = {
                get: function(a) {
                    return a.getAttribute(b, 4)
                }
            }
        }), l.optSelected || (n.propHooks.selected = {
            get: function(a) {
                var b = a.parentNode;
                return b && (b.selectedIndex, b.parentNode && b.parentNode.selectedIndex), null
            }
        }), n.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function() {
            n.propFix[this.toLowerCase()] = this
        }), l.enctype || (n.propFix.enctype = "encoding");
        var vc = /[\t\r\n\f]/g;
        n.fn.extend({
            addClass: function(a) {
                var b, c, d, e, f, g, h = 0,
                    i = this.length,
                    j = "string" == typeof a && a;
                if (n.isFunction(a)) return this.each(function(b) {
                    n(this).addClass(a.call(this, b, this.className))
                });
                if (j)
                    for (b = (a || "").match(F) || []; i > h; h++)
                        if (c = this[h], d = 1 === c.nodeType && (c.className ? (" " + c.className + " ").replace(vc, " ") : " ")) {
                            f = 0;
                            while (e = b[f++]) d.indexOf(" " + e + " ") < 0 && (d += e + " ");
                            g = n.trim(d), c.className !== g && (c.className = g)
                        }
                return this
            },
            removeClass: function(a) {
                var b, c, d, e, f, g, h = 0,
                    i = this.length,
                    j = 0 === arguments.length || "string" == typeof a && a;
                if (n.isFunction(a)) return this.each(function(b) {
                    n(this).removeClass(a.call(this, b, this.className))
                });
                if (j)
                    for (b = (a || "").match(F) || []; i > h; h++)
                        if (c = this[h], d = 1 === c.nodeType && (c.className ? (" " + c.className + " ").replace(vc, " ") : "")) {
                            f = 0;
                            while (e = b[f++])
                                while (d.indexOf(" " + e + " ") >= 0) d = d.replace(" " + e + " ", " ");
                            g = a ? n.trim(d) : "", c.className !== g && (c.className = g)
                        }
                return this
            },
            toggleClass: function(a, b) {
                var c = typeof a;
                return "boolean" == typeof b && "string" === c ? b ? this.addClass(a) : this.removeClass(a) : this.each(n.isFunction(a) ? function(c) {
                    n(this).toggleClass(a.call(this, c, this.className, b), b)
                } : function() {
                    if ("string" === c) {
                        var b, d = 0,
                            e = n(this),
                            f = a.match(F) || [];
                        while (b = f[d++]) e.hasClass(b) ? e.removeClass(b) : e.addClass(b)
                    } else(c === L || "boolean" === c) && (this.className && n._data(this, "__className__", this.className), this.className = this.className || a === !1 ? "" : n._data(this, "__className__") || "")
                })
            },
            hasClass: function(a) {
                for (var b = " " + a + " ", c = 0, d = this.length; d > c; c++)
                    if (1 === this[c].nodeType && (" " + this[c].className + " ").replace(vc, " ").indexOf(b) >= 0) return !0;
                return !1
            }
        }), n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "), function(a, b) {
            n.fn[b] = function(a, c) {
                return arguments.length > 0 ? this.on(b, null, a, c) : this.trigger(b)
            }
        }), n.fn.extend({
            hover: function(a, b) {
                return this.mouseenter(a).mouseleave(b || a)
            },
            bind: function(a, b, c) {
                return this.on(a, null, b, c)
            },
            unbind: function(a, b) {
                return this.off(a, null, b)
            },
            delegate: function(a, b, c, d) {
                return this.on(b, a, c, d)
            },
            undelegate: function(a, b, c) {
                return 1 === arguments.length ? this.off(a, "**") : this.off(b, a || "**", c)
            }
        });
        var wc = n.now(),
            xc = /\?/,
            yc = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
        n.parseJSON = function(b) {
            if (a.JSON && a.JSON.parse) return a.JSON.parse(b + "");
            var c, d = null,
                e = n.trim(b + "");
            return e && !n.trim(e.replace(yc, function(a, b, e, f) {
                return c && b && (d = 0), 0 === d ? a : (c = e || b, d += !f - !e, "")
            })) ? Function("return " + e)() : n.error("Invalid JSON: " + b)
        }, n.parseXML = function(b) {
            var c, d;
            if (!b || "string" != typeof b) return null;
            try {
                a.DOMParser ? (d = new DOMParser, c = d.parseFromString(b, "text/xml")) : (c = new ActiveXObject("Microsoft.XMLDOM"), c.async = "false", c.loadXML(b))
            } catch (e) {
                c = void 0
            }
            return c && c.documentElement && !c.getElementsByTagName("parsererror").length || n.error("Invalid XML: " + b), c
        };
        var zc, Ac, Bc = /#.*$/,
            Cc = /([?&])_=[^&]*/,
            Dc = /^(.*?):[ \t]*([^\r\n]*)\r?$/gm,
            Ec = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
            Fc = /^(?:GET|HEAD)$/,
            Gc = /^\/\//,
            Hc = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
            Ic = {},
            Jc = {},
            Kc = "*/".concat("*");
        try {
            Ac = location.href
        } catch (Lc) {
            Ac = z.createElement("a"), Ac.href = "", Ac = Ac.href
        }
        zc = Hc.exec(Ac.toLowerCase()) || [];
    
        function Mc(a) {
            return function(b, c) {
                "string" != typeof b && (c = b, b = "*");
                var d, e = 0,
                    f = b.toLowerCase().match(F) || [];
                if (n.isFunction(c))
                    while (d = f[e++]) "+" === d.charAt(0) ? (d = d.slice(1) || "*", (a[d] = a[d] || []).unshift(c)) : (a[d] = a[d] || []).push(c)
            }
        }
    
        function Nc(a, b, c, d) {
            var e = {},
                f = a === Jc;
    
            function g(h) {
                var i;
                return e[h] = !0, n.each(a[h] || [], function(a, h) {
                    var j = h(b, c, d);
                    return "string" != typeof j || f || e[j] ? f ? !(i = j) : void 0 : (b.dataTypes.unshift(j), g(j), !1)
                }), i
            }
            return g(b.dataTypes[0]) || !e["*"] && g("*")
        }
    
        function Oc(a, b) {
            var c, d, e = n.ajaxSettings.flatOptions || {};
            for (d in b) void 0 !== b[d] && ((e[d] ? a : c || (c = {}))[d] = b[d]);
            return c && n.extend(!0, a, c), a
        }
    
        function Pc(a, b, c) {
            var d, e, f, g, h = a.contents,
                i = a.dataTypes;
            while ("*" === i[0]) i.shift(), void 0 === e && (e = a.mimeType || b.getResponseHeader("Content-Type"));
            if (e)
                for (g in h)
                    if (h[g] && h[g].test(e)) {
                        i.unshift(g);
                        break
                    }
            if (i[0] in c) f = i[0];
            else {
                for (g in c) {
                    if (!i[0] || a.converters[g + " " + i[0]]) {
                        f = g;
                        break
                    }
                    d || (d = g)
                }
                f = f || d
            }
            return f ? (f !== i[0] && i.unshift(f), c[f]) : void 0
        }
    
        function Qc(a, b, c, d) {
            var e, f, g, h, i, j = {},
                k = a.dataTypes.slice();
            if (k[1])
                for (g in a.converters) j[g.toLowerCase()] = a.converters[g];
            f = k.shift();
            while (f)
                if (a.responseFields[f] && (c[a.responseFields[f]] = b), !i && d && a.dataFilter && (b = a.dataFilter(b, a.dataType)), i = f, f = k.shift())
                    if ("*" === f) f = i;
                    else if ("*" !== i && i !== f) {
                if (g = j[i + " " + f] || j["* " + f], !g)
                    for (e in j)
                        if (h = e.split(" "), h[1] === f && (g = j[i + " " + h[0]] || j["* " + h[0]])) {
                            g === !0 ? g = j[e] : j[e] !== !0 && (f = h[0], k.unshift(h[1]));
                            break
                        }
                if (g !== !0)
                    if (g && a["throws"]) b = g(b);
                    else try {
                        b = g(b)
                    } catch (l) {
                        return {
                            state: "parsererror",
                            error: g ? l : "No conversion from " + i + " to " + f
                        }
                    }
            }
            return {
                state: "success",
                data: b
            }
        }
        n.extend({
            active: 0,
            lastModified: {},
            etag: {},
            ajaxSettings: {
                url: Ac,
                type: "GET",
                isLocal: Ec.test(zc[1]),
                global: !0,
                processData: !0,
                async: !0,
                contentType: "application/x-www-form-urlencoded; charset=UTF-8",
                accepts: {
                    "*": Kc,
                    text: "text/plain",
                    html: "text/html",
                    xml: "application/xml, text/xml",
                    json: "application/json, text/javascript"
                },
                contents: {
                    xml: /xml/,
                    html: /html/,
                    json: /json/
                },
                responseFields: {
                    xml: "responseXML",
                    text: "responseText",
                    json: "responseJSON"
                },
                converters: {
                    "* text": String,
                    "text html": !0,
                    "text json": n.parseJSON,
                    "text xml": n.parseXML
                },
                flatOptions: {
                    url: !0,
                    context: !0
                }
            },
            ajaxSetup: function(a, b) {
                return b ? Oc(Oc(a, n.ajaxSettings), b) : Oc(n.ajaxSettings, a)
            },
            ajaxPrefilter: Mc(Ic),
            ajaxTransport: Mc(Jc),
            ajax: function(a, b) {
                "object" == typeof a && (b = a, a = void 0), b = b || {};
                var c, d, e, f, g, h, i, j, k = n.ajaxSetup({}, b),
                    l = k.context || k,
                    m = k.context && (l.nodeType || l.jquery) ? n(l) : n.event,
                    o = n.Deferred(),
                    p = n.Callbacks("once memory"),
                    q = k.statusCode || {},
                    r = {},
                    s = {},
                    t = 0,
                    u = "canceled",
                    v = {
                        readyState: 0,
                        getResponseHeader: function(a) {
                            var b;
                            if (2 === t) {
                                if (!j) {
                                    j = {};
                                    while (b = Dc.exec(f)) j[b[1].toLowerCase()] = b[2]
                                }
                                b = j[a.toLowerCase()]
                            }
                            return null == b ? null : b
                        },
                        getAllResponseHeaders: function() {
                            return 2 === t ? f : null
                        },
                        setRequestHeader: function(a, b) {
                            var c = a.toLowerCase();
                            return t || (a = s[c] = s[c] || a, r[a] = b), this
                        },
                        overrideMimeType: function(a) {
                            return t || (k.mimeType = a), this
                        },
                        statusCode: function(a) {
                            var b;
                            if (a)
                                if (2 > t)
                                    for (b in a) q[b] = [q[b], a[b]];
                                else v.always(a[v.status]);
                            return this
                        },
                        abort: function(a) {
                            var b = a || u;
                            return i && i.abort(b), x(0, b), this
                        }
                    };
                if (o.promise(v).complete = p.add, v.success = v.done, v.error = v.fail, k.url = ((a || k.url || Ac) + "").replace(Bc, "").replace(Gc, zc[1] + "//"), k.type = b.method || b.type || k.method || k.type, k.dataTypes = n.trim(k.dataType || "*").toLowerCase().match(F) || [""], null == k.crossDomain && (c = Hc.exec(k.url.toLowerCase()), k.crossDomain = !(!c || c[1] === zc[1] && c[2] === zc[2] && (c[3] || ("http:" === c[1] ? "80" : "443")) === (zc[3] || ("http:" === zc[1] ? "80" : "443")))), k.data && k.processData && "string" != typeof k.data && (k.data = n.param(k.data, k.traditional)), Nc(Ic, k, b, v), 2 === t) return v;
                h = k.global, h && 0 === n.active++ && n.event.trigger("ajaxStart"), k.type = k.type.toUpperCase(), k.hasContent = !Fc.test(k.type), e = k.url, k.hasContent || (k.data && (e = k.url += (xc.test(e) ? "&" : "?") + k.data, delete k.data), k.cache === !1 && (k.url = Cc.test(e) ? e.replace(Cc, "$1_=" + wc++) : e + (xc.test(e) ? "&" : "?") + "_=" + wc++)), k.ifModified && (n.lastModified[e] && v.setRequestHeader("If-Modified-Since", n.lastModified[e]), n.etag[e] && v.setRequestHeader("If-None-Match", n.etag[e])), (k.data && k.hasContent && k.contentType !== !1 || b.contentType) && v.setRequestHeader("Content-Type", k.contentType), v.setRequestHeader("Accept", k.dataTypes[0] && k.accepts[k.dataTypes[0]] ? k.accepts[k.dataTypes[0]] + ("*" !== k.dataTypes[0] ? ", " + Kc + "; q=0.01" : "") : k.accepts["*"]);
                for (d in k.headers) v.setRequestHeader(d, k.headers[d]);
                if (k.beforeSend && (k.beforeSend.call(l, v, k) === !1 || 2 === t)) return v.abort();
                u = "abort";
                for (d in {
                        success: 1,
                        error: 1,
                        complete: 1
                    }) v[d](k[d]);
                if (i = Nc(Jc, k, b, v)) {
                    v.readyState = 1, h && m.trigger("ajaxSend", [v, k]), k.async && k.timeout > 0 && (g = setTimeout(function() {
                        v.abort("timeout")
                    }, k.timeout));
                    try {
                        t = 1, i.send(r, x)
                    } catch (w) {
                        if (!(2 > t)) throw w;
                        x(-1, w)
                    }
                } else x(-1, "No Transport");
    
                function x(a, b, c, d) {
                    var j, r, s, u, w, x = b;
                    2 !== t && (t = 2, g && clearTimeout(g), i = void 0, f = d || "", v.readyState = a > 0 ? 4 : 0, j = a >= 200 && 300 > a || 304 === a, c && (u = Pc(k, v, c)), u = Qc(k, u, v, j), j ? (k.ifModified && (w = v.getResponseHeader("Last-Modified"), w && (n.lastModified[e] = w), w = v.getResponseHeader("etag"), w && (n.etag[e] = w)), 204 === a || "HEAD" === k.type ? x = "nocontent" : 304 === a ? x = "notmodified" : (x = u.state, r = u.data, s = u.error, j = !s)) : (s = x, (a || !x) && (x = "error", 0 > a && (a = 0))), v.status = a, v.statusText = (b || x) + "", j ? o.resolveWith(l, [r, x, v]) : o.rejectWith(l, [v, x, s]), v.statusCode(q), q = void 0, h && m.trigger(j ? "ajaxSuccess" : "ajaxError", [v, k, j ? r : s]), p.fireWith(l, [v, x]), h && (m.trigger("ajaxComplete", [v, k]), --n.active || n.event.trigger("ajaxStop")))
                }
                return v
            },
            getJSON: function(a, b, c) {
                return n.get(a, b, c, "json")
            },
            getScript: function(a, b) {
                return n.get(a, void 0, b, "script")
            }
        }), n.each(["get", "post"], function(a, b) {
            n[b] = function(a, c, d, e) {
                return n.isFunction(c) && (e = e || d, d = c, c = void 0), n.ajax({
                    url: a,
                    type: b,
                    dataType: e,
                    data: c,
                    success: d
                })
            }
        }), n.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function(a, b) {
            n.fn[b] = function(a) {
                return this.on(b, a)
            }
        }), n._evalUrl = function(a) {
            return n.ajax({
                url: a,
                type: "GET",
                dataType: "script",
                async: !1,
                global: !1,
                "throws": !0
            })
        }, n.fn.extend({
            wrapAll: function(a) {
                if (n.isFunction(a)) return this.each(function(b) {
                    n(this).wrapAll(a.call(this, b))
                });
                if (this[0]) {
                    var b = n(a, this[0].ownerDocument).eq(0).clone(!0);
                    this[0].parentNode && b.insertBefore(this[0]), b.map(function() {
                        var a = this;
                        while (a.firstChild && 1 === a.firstChild.nodeType) a = a.firstChild;
                        return a
                    }).append(this)
                }
                return this
            },
            wrapInner: function(a) {
                return this.each(n.isFunction(a) ? function(b) {
                    n(this).wrapInner(a.call(this, b))
                } : function() {
                    var b = n(this),
                        c = b.contents();
                    c.length ? c.wrapAll(a) : b.append(a)
                })
            },
            wrap: function(a) {
                var b = n.isFunction(a);
                return this.each(function(c) {
                    n(this).wrapAll(b ? a.call(this, c) : a)
                })
            },
            unwrap: function() {
                return this.parent().each(function() {
                    n.nodeName(this, "body") || n(this).replaceWith(this.childNodes)
                }).end()
            }
        }), n.expr.filters.hidden = function(a) {
            return a.offsetWidth <= 0 && a.offsetHeight <= 0 || !l.reliableHiddenOffsets() && "none" === (a.style && a.style.display || n.css(a, "display"))
        }, n.expr.filters.visible = function(a) {
            return !n.expr.filters.hidden(a)
        };
        var Rc = /%20/g,
            Sc = /\[\]$/,
            Tc = /\r?\n/g,
            Uc = /^(?:submit|button|image|reset|file)$/i,
            Vc = /^(?:input|select|textarea|keygen)/i;
    
        function Wc(a, b, c, d) {
            var e;
            if (n.isArray(b)) n.each(b, function(b, e) {
                c || Sc.test(a) ? d(a, e) : Wc(a + "[" + ("object" == typeof e ? b : "") + "]", e, c, d)
            });
            else if (c || "object" !== n.type(b)) d(a, b);
            else
                for (e in b) Wc(a + "[" + e + "]", b[e], c, d)
        }
        n.param = function(a, b) {
            var c, d = [],
                e = function(a, b) {
                    b = n.isFunction(b) ? b() : null == b ? "" : b, d[d.length] = encodeURIComponent(a) + "=" + encodeURIComponent(b)
                };
            if (void 0 === b && (b = n.ajaxSettings && n.ajaxSettings.traditional), n.isArray(a) || a.jquery && !n.isPlainObject(a)) n.each(a, function() {
                e(this.name, this.value)
            });
            else
                for (c in a) Wc(c, a[c], b, e);
            return d.join("&").replace(Rc, "+")
        }, n.fn.extend({
            serialize: function() {
                return n.param(this.serializeArray())
            },
            serializeArray: function() {
                return this.map(function() {
                    var a = n.prop(this, "elements");
                    return a ? n.makeArray(a) : this
                }).filter(function() {
                    var a = this.type;
                    return this.name && !n(this).is(":disabled") && Vc.test(this.nodeName) && !Uc.test(a) && (this.checked || !X.test(a))
                }).map(function(a, b) {
                    var c = n(this).val();
                    return null == c ? null : n.isArray(c) ? n.map(c, function(a) {
                        return {
                            name: b.name,
                            value: a.replace(Tc, "\r\n")
                        }
                    }) : {
                        name: b.name,
                        value: c.replace(Tc, "\r\n")
                    }
                }).get()
            }
        }), n.ajaxSettings.xhr = void 0 !== a.ActiveXObject ? function() {
            return !this.isLocal && /^(get|post|head|put|delete|options)$/i.test(this.type) && $c() || _c()
        } : $c;
        var Xc = 0,
            Yc = {},
            Zc = n.ajaxSettings.xhr();
        a.ActiveXObject && n(a).on("unload", function() {
            for (var a in Yc) Yc[a](void 0, !0)
        }), l.cors = !!Zc && "withCredentials" in Zc, Zc = l.ajax = !!Zc, Zc && n.ajaxTransport(function(a) {
            if (!a.crossDomain || l.cors) {
                var b;
                return {
                    send: function(c, d) {
                        var e, f = a.xhr(),
                            g = ++Xc;
                        if (f.open(a.type, a.url, a.async, a.username, a.password), a.xhrFields)
                            for (e in a.xhrFields) f[e] = a.xhrFields[e];
                        a.mimeType && f.overrideMimeType && f.overrideMimeType(a.mimeType), a.crossDomain || c["X-Requested-With"] || (c["X-Requested-With"] = "XMLHttpRequest");
                        for (e in c) void 0 !== c[e] && f.setRequestHeader(e, c[e] + "");
                        f.send(a.hasContent && a.data || null), b = function(c, e) {
                            var h, i, j;
                            if (b && (e || 4 === f.readyState))
                                if (delete Yc[g], b = void 0, f.onreadystatechange = n.noop, e) 4 !== f.readyState && f.abort();
                                else {
                                    j = {}, h = f.status, "string" == typeof f.responseText && (j.text = f.responseText);
                                    try {
                                        i = f.statusText
                                    } catch (k) {
                                        i = ""
                                    }
                                    h || !a.isLocal || a.crossDomain ? 1223 === h && (h = 204) : h = j.text ? 200 : 404
                                }
                            j && d(h, i, j, f.getAllResponseHeaders())
                        }, a.async ? 4 === f.readyState ? setTimeout(b) : f.onreadystatechange = Yc[g] = b : b()
                    },
                    abort: function() {
                        b && b(void 0, !0)
                    }
                }
            }
        });
    
        function $c() {
            try {
                return new a.XMLHttpRequest
            } catch (b) {}
        }
    
        function _c() {
            try {
                return new a.ActiveXObject("Microsoft.XMLHTTP")
            } catch (b) {}
        }
        n.ajaxSetup({
            accepts: {
                script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
            },
            contents: {
                script: /(?:java|ecma)script/
            },
            converters: {
                "text script": function(a) {
                    return n.globalEval(a), a
                }
            }
        }), n.ajaxPrefilter("script", function(a) {
            void 0 === a.cache && (a.cache = !1), a.crossDomain && (a.type = "GET", a.global = !1)
        }), n.ajaxTransport("script", function(a) {
            if (a.crossDomain) {
                var b, c = z.head || n("head")[0] || z.documentElement;
                return {
                    send: function(d, e) {
                        b = z.createElement("script"), b.async = !0, a.scriptCharset && (b.charset = a.scriptCharset), b.src = a.url, b.onload = b.onreadystatechange = function(a, c) {
                            (c || !b.readyState || /loaded|complete/.test(b.readyState)) && (b.onload = b.onreadystatechange = null, b.parentNode && b.parentNode.removeChild(b), b = null, c || e(200, "success"))
                        }, c.insertBefore(b, c.firstChild)
                    },
                    abort: function() {
                        b && b.onload(void 0, !0)
                    }
                }
            }
        });
        var ad = [],
            bd = /(=)\?(?=&|$)|\?\?/;
        n.ajaxSetup({
            jsonp: "callback",
            jsonpCallback: function() {
                var a = ad.pop() || n.expando + "_" + wc++;
                return this[a] = !0, a
            }
        }), n.ajaxPrefilter("json jsonp", function(b, c, d) {
            var e, f, g, h = b.jsonp !== !1 && (bd.test(b.url) ? "url" : "string" == typeof b.data && !(b.contentType || "").indexOf("application/x-www-form-urlencoded") && bd.test(b.data) && "data");
            return h || "jsonp" === b.dataTypes[0] ? (e = b.jsonpCallback = n.isFunction(b.jsonpCallback) ? b.jsonpCallback() : b.jsonpCallback, h ? b[h] = b[h].replace(bd, "$1" + e) : b.jsonp !== !1 && (b.url += (xc.test(b.url) ? "&" : "?") + b.jsonp + "=" + e), b.converters["script json"] = function() {
                return g || n.error(e + " was not called"), g[0]
            }, b.dataTypes[0] = "json", f = a[e], a[e] = function() {
                g = arguments
            }, d.always(function() {
                a[e] = f, b[e] && (b.jsonpCallback = c.jsonpCallback, ad.push(e)), g && n.isFunction(f) && f(g[0]), g = f = void 0
            }), "script") : void 0
        }), n.parseHTML = function(a, b, c) {
            if (!a || "string" != typeof a) return null;
            "boolean" == typeof b && (c = b, b = !1), b = b || z;
            var d = v.exec(a),
                e = !c && [];
            return d ? [b.createElement(d[1])] : (d = n.buildFragment([a], b, e), e && e.length && n(e).remove(), n.merge([], d.childNodes))
        };
        var cd = n.fn.load;
        n.fn.load = function(a, b, c) {
            if ("string" != typeof a && cd) return cd.apply(this, arguments);
            var d, e, f, g = this,
                h = a.indexOf(" ");
            return h >= 0 && (d = a.slice(h, a.length), a = a.slice(0, h)), n.isFunction(b) ? (c = b, b = void 0) : b && "object" == typeof b && (f = "POST"), g.length > 0 && n.ajax({
                url: a,
                type: f,
                dataType: "html",
                data: b
            }).done(function(a) {
                e = arguments, g.html(d ? n("<div>").append(n.parseHTML(a)).find(d) : a)
            }).complete(c && function(a, b) {
                g.each(c, e || [a.responseText, b, a])
            }), this
        }, n.expr.filters.animated = function(a) {
            return n.grep(n.timers, function(b) {
                return a === b.elem
            }).length
        };
        var dd = a.document.documentElement;
    
        function ed(a) {
            return n.isWindow(a) ? a : 9 === a.nodeType ? a.defaultView || a.parentWindow : !1
        }
        n.offset = {
            setOffset: function(a, b, c) {
                var d, e, f, g, h, i, j, k = n.css(a, "position"),
                    l = n(a),
                    m = {};
                "static" === k && (a.style.position = "relative"), h = l.offset(), f = n.css(a, "top"), i = n.css(a, "left"), j = ("absolute" === k || "fixed" === k) && n.inArray("auto", [f, i]) > -1, j ? (d = l.position(), g = d.top, e = d.left) : (g = parseFloat(f) || 0, e = parseFloat(i) || 0), n.isFunction(b) && (b = b.call(a, c, h)), null != b.top && (m.top = b.top - h.top + g), null != b.left && (m.left = b.left - h.left + e), "using" in b ? b.using.call(a, m) : l.css(m)
            }
        }, n.fn.extend({
            offset: function(a) {
                if (arguments.length) return void 0 === a ? this : this.each(function(b) {
                    n.offset.setOffset(this, a, b)
                });
                var b, c, d = {
                        top: 0,
                        left: 0
                    },
                    e = this[0],
                    f = e && e.ownerDocument;
                if (f) return b = f.documentElement, n.contains(b, e) ? (typeof e.getBoundingClientRect !== L && (d = e.getBoundingClientRect()), c = ed(f), {
                    top: d.top + (c.pageYOffset || b.scrollTop) - (b.clientTop || 0),
                    left: d.left + (c.pageXOffset || b.scrollLeft) - (b.clientLeft || 0)
                }) : d
            },
            position: function() {
                if (this[0]) {
                    var a, b, c = {
                            top: 0,
                            left: 0
                        },
                        d = this[0];
                    return "fixed" === n.css(d, "position") ? b = d.getBoundingClientRect() : (a = this.offsetParent(), b = this.offset(), n.nodeName(a[0], "html") || (c = a.offset()), c.top += n.css(a[0], "borderTopWidth", !0), c.left += n.css(a[0], "borderLeftWidth", !0)), {
                        top: b.top - c.top - n.css(d, "marginTop", !0),
                        left: b.left - c.left - n.css(d, "marginLeft", !0)
                    }
                }
            },
            offsetParent: function() {
                return this.map(function() {
                    var a = this.offsetParent || dd;
                    while (a && !n.nodeName(a, "html") && "static" === n.css(a, "position")) a = a.offsetParent;
                    return a || dd
                })
            }
        }), n.each({
            scrollLeft: "pageXOffset",
            scrollTop: "pageYOffset"
        }, function(a, b) {
            var c = /Y/.test(b);
            n.fn[a] = function(d) {
                return W(this, function(a, d, e) {
                    var f = ed(a);
                    return void 0 === e ? f ? b in f ? f[b] : f.document.documentElement[d] : a[d] : void(f ? f.scrollTo(c ? n(f).scrollLeft() : e, c ? e : n(f).scrollTop()) : a[d] = e)
                }, a, d, arguments.length, null)
            }
        }), n.each(["top", "left"], function(a, b) {
            n.cssHooks[b] = Mb(l.pixelPosition, function(a, c) {
                return c ? (c = Kb(a, b), Ib.test(c) ? n(a).position()[b] + "px" : c) : void 0
            })
        }), n.each({
            Height: "height",
            Width: "width"
        }, function(a, b) {
            n.each({
                padding: "inner" + a,
                content: b,
                "": "outer" + a
            }, function(c, d) {
                n.fn[d] = function(d, e) {
                    var f = arguments.length && (c || "boolean" != typeof d),
                        g = c || (d === !0 || e === !0 ? "margin" : "border");
                    return W(this, function(b, c, d) {
                        var e;
                        return n.isWindow(b) ? b.document.documentElement["client" + a] : 9 === b.nodeType ? (e = b.documentElement, Math.max(b.body["scroll" + a], e["scroll" + a], b.body["offset" + a], e["offset" + a], e["client" + a])) : void 0 === d ? n.css(b, c, g) : n.style(b, c, d, g)
                    }, b, f ? d : void 0, f, null)
                }
            })
        }), n.fn.size = function() {
            return this.length
        }, n.fn.andSelf = n.fn.addBack, "function" == typeof define && define.amd && define("jquery", [], function() {
            return n
        });
        var fd = a.jQuery,
            gd = a.$;
        return n.noConflict = function(b) {
            return a.$ === n && (a.$ = gd), b && a.jQuery === n && (a.jQuery = fd), n
        }, typeof b === L && (a.jQuery = a.$ = n), n
    });
    /*! RESOURCE: /scripts/thirdparty/cometd/jquery/jquery-1.11.0_no_conflict.js */
    (function() {
        window.jQuery1110 = jQuery.noConflict(true);
    })();;
    /*! RESOURCE: /scripts/thirdparty/cometd/org/cometd.js */
    this.org = this.org || {};
    org.cometd = {};
    org.cometd.JSON = {};
    org.cometd.JSON.toJSON = org.cometd.JSON.fromJSON = function(object) {
        throw 'Abstract';
    };
    org.cometd.Utils = {};
    org.cometd.Utils.isString = function(value) {
        if (value === undefined || value === null) {
            return false;
        }
        return typeof value === 'string' || value instanceof String;
    };
    org.cometd.Utils.isArray = function(value) {
        if (value === undefined || value === null) {
            return false;
        }
        return value instanceof Array;
    };
    org.cometd.Utils.inArray = function(element, array) {
        for (var i = 0; i < array.length; ++i) {
            if (element === array[i]) {
                return i;
            }
        }
        return -1;
    };
    org.cometd.Utils.setTimeout = function(cometd, funktion, delay) {
        return window.setTimeout(function() {
            try {
                funktion();
            } catch (x) {
                cometd._debug('Exception invoking timed function', funktion, x);
            }
        }, delay);
    };
    org.cometd.Utils.clearTimeout = function(timeoutHandle) {
        window.clearTimeout(timeoutHandle);
    };
    org.cometd.TransportRegistry = function() {
        var _types = [];
        var _transports = {};
        this.getTransportTypes = function() {
            return _types.slice(0);
        };
        this.findTransportTypes = function(version, crossDomain, url) {
            var result = [];
            for (var i = 0; i < _types.length; ++i) {
                var type = _types[i];
                if (_transports[type].accept(version, crossDomain, url) === true) {
                    result.push(type);
                }
            }
            return result;
        };
        this.negotiateTransport = function(types, version, crossDomain, url) {
            for (var i = 0; i < _types.length; ++i) {
                var type = _types[i];
                for (var j = 0; j < types.length; ++j) {
                    if (type === types[j]) {
                        var transport = _transports[type];
                        if (transport.accept(version, crossDomain, url) === true) {
                            return transport;
                        }
                    }
                }
            }
            return null;
        };
        this.add = function(type, transport, index) {
            var existing = false;
            for (var i = 0; i < _types.length; ++i) {
                if (_types[i] === type) {
                    existing = true;
                    break;
                }
            }
            if (!existing) {
                if (typeof index !== 'number') {
                    _types.push(type);
                } else {
                    _types.splice(index, 0, type);
                }
                _transports[type] = transport;
            }
            return !existing;
        };
        this.find = function(type) {
            for (var i = 0; i < _types.length; ++i) {
                if (_types[i] === type) {
                    return _transports[type];
                }
            }
            return null;
        };
        this.remove = function(type) {
            for (var i = 0; i < _types.length; ++i) {
                if (_types[i] === type) {
                    _types.splice(i, 1);
                    var transport = _transports[type];
                    delete _transports[type];
                    return transport;
                }
            }
            return null;
        };
        this.clear = function() {
            _types = [];
            _transports = {};
        };
        this.reset = function() {
            for (var i = 0; i < _types.length; ++i) {
                _transports[_types[i]].reset();
            }
        };
    };
    org.cometd.Transport = function() {
        var _type;
        var _cometd;
        this.registered = function(type, cometd) {
            _type = type;
            _cometd = cometd;
        };
        this.unregistered = function() {
            _type = null;
            _cometd = null;
        };
        this._debug = function() {
            _cometd._debug.apply(_cometd, arguments);
        };
        this._mixin = function() {
            return _cometd._mixin.apply(_cometd, arguments);
        };
        this.getConfiguration = function() {
            return _cometd.getConfiguration();
        };
        this.getAdvice = function() {
            return _cometd.getAdvice();
        };
        this.setTimeout = function(funktion, delay) {
            return org.cometd.Utils.setTimeout(_cometd, funktion, delay);
        };
        this.clearTimeout = function(handle) {
            org.cometd.Utils.clearTimeout(handle);
        };
        this.convertToMessages = function(response) {
            if (org.cometd.Utils.isString(response)) {
                try {
                    return org.cometd.JSON.fromJSON(response);
                } catch (x) {
                    this._debug('Could not convert to JSON the following string', '"' + response + '"');
                    throw x;
                }
            }
            if (org.cometd.Utils.isArray(response)) {
                return response;
            }
            if (response === undefined || response === null) {
                return [];
            }
            if (response instanceof Object) {
                return [response];
            }
            throw 'Conversion Error ' + response + ', typeof ' + (typeof response);
        };
        this.accept = function(version, crossDomain, url) {
            throw 'Abstract';
        };
        this.getType = function() {
            return _type;
        };
        this.send = function(envelope, metaConnect) {
            throw 'Abstract';
        };
        this.reset = function() {
            this._debug('Transport', _type, 'reset');
        };
        this.abort = function() {
            this._debug('Transport', _type, 'aborted');
        };
        this.toString = function() {
            return this.getType();
        };
    };
    org.cometd.Transport.derive = function(baseObject) {
        function F() {}
        F.prototype = baseObject;
        return new F();
    };
    org.cometd.RequestTransport = function() {
        var _super = new org.cometd.Transport();
        var _self = org.cometd.Transport.derive(_super);
        var _requestIds = 0;
        var _metaConnectRequest = null;
        var _requests = [];
        var _envelopes = [];
    
        function _coalesceEnvelopes(envelope) {
            while (_envelopes.length > 0) {
                var envelopeAndRequest = _envelopes[0];
                var newEnvelope = envelopeAndRequest[0];
                var newRequest = envelopeAndRequest[1];
                if (newEnvelope.url === envelope.url &&
                    newEnvelope.sync === envelope.sync) {
                    _envelopes.shift();
                    envelope.messages = envelope.messages.concat(newEnvelope.messages);
                    this._debug('Coalesced', newEnvelope.messages.length, 'messages from request', newRequest.id);
                    continue;
                }
                break;
            }
        }
    
        function _transportSend(envelope, request) {
            this.transportSend(envelope, request);
            request.expired = false;
            if (!envelope.sync) {
                var maxDelay = this.getConfiguration().maxNetworkDelay;
                var delay = maxDelay;
                if (request.metaConnect === true) {
                    delay += this.getAdvice().timeout;
                }
                this._debug('Transport', this.getType(), 'waiting at most', delay, 'ms for the response, maxNetworkDelay', maxDelay);
                var self = this;
                request.timeout = this.setTimeout(function() {
                    request.expired = true;
                    var errorMessage = 'Request ' + request.id + ' of transport ' + self.getType() + ' exceeded ' + delay + ' ms max network delay';
                    var failure = {
                        reason: errorMessage
                    };
                    var xhr = request.xhr;
                    failure.httpCode = self.xhrStatus(xhr);
                    self.abortXHR(xhr);
                    self._debug(errorMessage);
                    self.complete(request, false, request.metaConnect);
                    envelope.onFailure(xhr, envelope.messages, failure);
                }, delay);
            }
        }
    
        function _queueSend(envelope) {
            var requestId = ++_requestIds;
            var request = {
                id: requestId,
                metaConnect: false
            };
            if (_requests.length < this.getConfiguration().maxConnections - 1) {
                _requests.push(request);
                _transportSend.call(this, envelope, request);
            } else {
                this._debug('Transport', this.getType(), 'queueing request', requestId, 'envelope', envelope);
                _envelopes.push([envelope, request]);
            }
        }
    
        function _metaConnectComplete(request) {
            var requestId = request.id;
            this._debug('Transport', this.getType(), 'metaConnect complete, request', requestId);
            if (_metaConnectRequest !== null && _metaConnectRequest.id !== requestId) {
                throw 'Longpoll request mismatch, completing request ' + requestId;
            }
            _metaConnectRequest = null;
        }
    
        function _complete(request, success) {
            var index = org.cometd.Utils.inArray(request, _requests);
            if (index >= 0) {
                _requests.splice(index, 1);
            }
            if (_envelopes.length > 0) {
                var envelopeAndRequest = _envelopes.shift();
                var nextEnvelope = envelopeAndRequest[0];
                var nextRequest = envelopeAndRequest[1];
                this._debug('Transport dequeued request', nextRequest.id);
                if (success) {
                    if (this.getConfiguration().autoBatch) {
                        _coalesceEnvelopes.call(this, nextEnvelope);
                    }
                    _queueSend.call(this, nextEnvelope);
                    this._debug('Transport completed request', request.id, nextEnvelope);
                } else {
                    var self = this;
                    this.setTimeout(function() {
                        self.complete(nextRequest, false, nextRequest.metaConnect);
                        var failure = {
                            reason: 'Previous request failed'
                        };
                        var xhr = nextRequest.xhr;
                        failure.httpCode = self.xhrStatus(xhr);
                        nextEnvelope.onFailure(xhr, nextEnvelope.messages, failure);
                    }, 0);
                }
            }
        }
        _self.complete = function(request, success, metaConnect) {
            if (metaConnect) {
                _metaConnectComplete.call(this, request);
            } else {
                _complete.call(this, request, success);
            }
        };
        _self.transportSend = function(envelope, request) {
            throw 'Abstract';
        };
        _self.transportSuccess = function(envelope, request, responses) {
            if (!request.expired) {
                this.clearTimeout(request.timeout);
                this.complete(request, true, request.metaConnect);
                if (responses && responses.length > 0) {
                    envelope.onSuccess(responses);
                } else {
                    envelope.onFailure(request.xhr, envelope.messages, {
                        httpCode: 204
                    });
                }
            }
        };
        _self.transportFailure = function(envelope, request, failure) {
            if (!request.expired) {
                this.clearTimeout(request.timeout);
                this.complete(request, false, request.metaConnect);
                envelope.onFailure(request.xhr, envelope.messages, failure);
            }
        };
    
        function _metaConnectSend(envelope) {
            if (_metaConnectRequest !== null) {
                throw 'Concurrent metaConnect requests not allowed, request id=' + _metaConnectRequest.id + ' not yet completed';
            }
            var requestId = ++_requestIds;
            this._debug('Transport', this.getType(), 'metaConnect send, request', requestId, 'envelope', envelope);
            var request = {
                id: requestId,
                metaConnect: true
            };
            _transportSend.call(this, envelope, request);
            _metaConnectRequest = request;
        }
        _self.send = function(envelope, metaConnect) {
            if (metaConnect) {
                _metaConnectSend.call(this, envelope);
            } else {
                _queueSend.call(this, envelope);
            }
        };
        _self.abort = function() {
            _super.abort();
            for (var i = 0; i < _requests.length; ++i) {
                var request = _requests[i];
                this._debug('Aborting request', request);
                this.abortXHR(request.xhr);
            }
            if (_metaConnectRequest) {
                this._debug('Aborting metaConnect request', _metaConnectRequest);
                this.abortXHR(_metaConnectRequest.xhr);
            }
            this.reset();
        };
        _self.reset = function() {
            _super.reset();
            _metaConnectRequest = null;
            _requests = [];
            _envelopes = [];
        };
        _self.abortXHR = function(xhr) {
            if (xhr) {
                try {
                    xhr.abort();
                } catch (x) {
                    this._debug(x);
                }
            }
        };
        _self.xhrStatus = function(xhr) {
            if (xhr) {
                try {
                    return xhr.status;
                } catch (x) {
                    this._debug(x);
                }
            }
            return -1;
        };
        return _self;
    };
    org.cometd.LongPollingTransport = function() {
        var _super = new org.cometd.RequestTransport();
        var _self = org.cometd.Transport.derive(_super);
        var _supportsCrossDomain = true;
        _self.accept = function(version, crossDomain, url) {
            return _supportsCrossDomain || !crossDomain;
        };
        _self.xhrSend = function(packet) {
            throw 'Abstract';
        };
        _self.transportSend = function(envelope, request) {
            this._debug('Transport', this.getType(), 'sending request', request.id, 'envelope', envelope);
            var self = this;
            try {
                var sameStack = true;
                request.xhr = this.xhrSend({
                    transport: this,
                    url: envelope.url,
                    sync: envelope.sync,
                    headers: this.getConfiguration().requestHeaders,
                    body: org.cometd.JSON.toJSON(envelope.messages),
                    onSuccess: function(response) {
                        self._debug('Transport', self.getType(), 'received response', response);
                        var success = false;
                        try {
                            var received = self.convertToMessages(response);
                            if (received.length === 0) {
                                _supportsCrossDomain = false;
                                self.transportFailure(envelope, request, {
                                    httpCode: 204
                                });
                            } else {
                                success = true;
                                self.transportSuccess(envelope, request, received);
                            }
                        } catch (x) {
                            self._debug(x);
                            if (!success) {
                                _supportsCrossDomain = false;
                                var failure = {
                                    exception: x
                                };
                                failure.httpCode = self.xhrStatus(request.xhr);
                                self.transportFailure(envelope, request, failure);
                            }
                        }
                    },
                    onError: function(reason, exception) {
                        _supportsCrossDomain = false;
                        var failure = {
                            reason: reason,
                            exception: exception
                        };
                        failure.httpCode = self.xhrStatus(request.xhr);
                        if (sameStack) {
                            self.setTimeout(function() {
                                self.transportFailure(envelope, request, failure);
                            }, 0);
                        } else {
                            self.transportFailure(envelope, request, failure);
                        }
                    }
                });
                sameStack = false;
            } catch (x) {
                _supportsCrossDomain = false;
                this.setTimeout(function() {
                    self.transportFailure(envelope, request, {
                        exception: x
                    });
                }, 0);
            }
        };
        _self.reset = function() {
            _super.reset();
            _supportsCrossDomain = true;
        };
        return _self;
    };
    org.cometd.CallbackPollingTransport = function() {
        var _super = new org.cometd.RequestTransport();
        var _self = org.cometd.Transport.derive(_super);
        var _maxLength = 2000;
        _self.accept = function(version, crossDomain, url) {
            return true;
        };
        _self.jsonpSend = function(packet) {
            throw 'Abstract';
        };
        _self.transportSend = function(envelope, request) {
            var self = this;
            var start = 0;
            var length = envelope.messages.length;
            var lengths = [];
            while (length > 0) {
                var json = org.cometd.JSON.toJSON(envelope.messages.slice(start, start + length));
                var urlLength = envelope.url.length + encodeURI(json).length;
                if (urlLength > _maxLength) {
                    if (length === 1) {
                        this.setTimeout(function() {
                            self.transportFailure(envelope, request, {
                                reason: 'Bayeux message too big, max is ' + _maxLength
                            });
                        }, 0);
                        return;
                    }
                    --length;
                    continue;
                }
                lengths.push(length);
                start += length;
                length = envelope.messages.length - start;
            }
            var envelopeToSend = envelope;
            if (lengths.length > 1) {
                var begin = 0;
                var end = lengths[0];
                this._debug('Transport', this.getType(), 'split', envelope.messages.length, 'messages into', lengths.join(' + '));
                envelopeToSend = this._mixin(false, {}, envelope);
                envelopeToSend.messages = envelope.messages.slice(begin, end);
                envelopeToSend.onSuccess = envelope.onSuccess;
                envelopeToSend.onFailure = envelope.onFailure;
                for (var i = 1; i < lengths.length; ++i) {
                    var nextEnvelope = this._mixin(false, {}, envelope);
                    begin = end;
                    end += lengths[i];
                    nextEnvelope.messages = envelope.messages.slice(begin, end);
                    nextEnvelope.onSuccess = envelope.onSuccess;
                    nextEnvelope.onFailure = envelope.onFailure;
                    this.send(nextEnvelope, request.metaConnect);
                }
            }
            this._debug('Transport', this.getType(), 'sending request', request.id, 'envelope', envelopeToSend);
            try {
                var sameStack = true;
                this.jsonpSend({
                    transport: this,
                    url: envelopeToSend.url,
                    sync: envelopeToSend.sync,
                    headers: this.getConfiguration().requestHeaders,
                    body: org.cometd.JSON.toJSON(envelopeToSend.messages),
                    onSuccess: function(responses) {
                        var success = false;
                        try {
                            var received = self.convertToMessages(responses);
                            if (received.length === 0) {
                                self.transportFailure(envelopeToSend, request, {
                                    httpCode: 204
                                });
                            } else {
                                success = true;
                                self.transportSuccess(envelopeToSend, request, received);
                            }
                        } catch (x) {
                            self._debug(x);
                            if (!success) {
                                self.transportFailure(envelopeToSend, request, {
                                    exception: x
                                });
                            }
                        }
                    },
                    onError: function(reason, exception) {
                        var failure = {
                            reason: reason,
                            exception: exception
                        };
                        if (sameStack) {
                            self.setTimeout(function() {
                                self.transportFailure(envelopeToSend, request, failure);
                            }, 0);
                        } else {
                            self.transportFailure(envelopeToSend, request, failure);
                        }
                    }
                });
                sameStack = false;
            } catch (xx) {
                this.setTimeout(function() {
                    self.transportFailure(envelopeToSend, request, {
                        exception: xx
                    });
                }, 0);
            }
        };
        return _self;
    };
    org.cometd.WebSocketTransport = function() {
        var _super = new org.cometd.Transport();
        var _self = org.cometd.Transport.derive(_super);
        var _cometd;
        var _webSocketSupported = true;
        var _webSocketConnected = false;
        var _stickyReconnect = true;
        var _envelopes = {};
        var _timeouts = {};
        var _connecting = false;
        var _webSocket = null;
        var _connected = false;
        var _successCallback = null;
        _self.reset = function() {
            _super.reset();
            _webSocketSupported = true;
            _webSocketConnected = false;
            _stickyReconnect = true;
            _envelopes = {};
            _timeouts = {};
            _connecting = false;
            _webSocket = null;
            _connected = false;
            _successCallback = null;
        };
    
        function _websocketConnect() {
            if (_connecting) {
                return;
            }
            _connecting = true;
            var url = _cometd.getURL().replace(/^http/, 'ws');
            this._debug('Transport', this.getType(), 'connecting to URL', url);
            try {
                var protocol = _cometd.getConfiguration().protocol;
                var webSocket = protocol ? new org.cometd.WebSocket(url, protocol) : new org.cometd.WebSocket(url);
            } catch (x) {
                _webSocketSupported = false;
                this._debug('Exception while creating WebSocket object', x);
                throw x;
            }
            _stickyReconnect = _cometd.getConfiguration().stickyReconnect !== false;
            var self = this;
            var connectTimer = null;
            var connectTimeout = _cometd.getConfiguration().connectTimeout;
            if (connectTimeout > 0) {
                connectTimer = this.setTimeout(function() {
                    connectTimer = null;
                    self._debug('Transport', self.getType(), 'timed out while connecting to URL', url, ':', connectTimeout, 'ms');
                    var event = {
                        code: 1000,
                        reason: 'Connect Timeout'
                    };
                    self.webSocketClose(webSocket, event.code, event.reason);
                    self.onClose(webSocket, event);
                }, connectTimeout);
            }
            var onopen = function() {
                self._debug('WebSocket opened', webSocket);
                _connecting = false;
                if (connectTimer) {
                    self.clearTimeout(connectTimer);
                    connectTimer = null;
                }
                if (_webSocket) {
                    _cometd._warn('Closing Extra WebSocket Connections', webSocket, _webSocket);
                    self.webSocketClose(webSocket, 1000, 'Extra Connection');
                } else {
                    self.onOpen(webSocket);
                }
            };
            var onclose = function(event) {
                event = event || {
                    code: 1000
                };
                self._debug('WebSocket closing', webSocket, event);
                _connecting = false;
                if (connectTimer) {
                    self.clearTimeout(connectTimer);
                    connectTimer = null;
                }
                if (_webSocket !== null && webSocket !== _webSocket) {
                    self._debug('Closed Extra WebSocket Connection', webSocket);
                } else {
                    self.onClose(webSocket, event);
                }
            };
            var onmessage = function(message) {
                self._debug('WebSocket message', message, webSocket);
                if (webSocket !== _webSocket) {
                    _cometd._warn('Extra WebSocket Connections', webSocket, _webSocket);
                }
                self.onMessage(webSocket, message);
            };
            webSocket.onopen = onopen;
            webSocket.onclose = onclose;
            webSocket.onerror = function() {
                onclose({
                    code: 1002,
                    reason: 'Error'
                });
            };
            webSocket.onmessage = onmessage;
            this._debug('Transport', this.getType(), 'configured callbacks on', webSocket);
        }
    
        function _webSocketSend(webSocket, envelope, metaConnect) {
            var json = org.cometd.JSON.toJSON(envelope.messages);
            webSocket.send(json);
            this._debug('Transport', this.getType(), 'sent', envelope, 'metaConnect =', metaConnect);
            var maxDelay = this.getConfiguration().maxNetworkDelay;
            var delay = maxDelay;
            if (metaConnect) {
                delay += this.getAdvice().timeout;
                _connected = true;
            }
            var self = this;
            var messageIds = [];
            for (var i = 0; i < envelope.messages.length; ++i) {
                (function() {
                    var message = envelope.messages[i];
                    if (message.id) {
                        messageIds.push(message.id);
                        _timeouts[message.id] = this.setTimeout(function() {
                            self._debug('Transport', self.getType(), 'timing out message', message.id, 'after', delay, 'on', webSocket);
                            var event = {
                                code: 1000,
                                reason: 'Message Timeout'
                            };
                            self.webSocketClose(webSocket, event.code, event.reason);
                            self.onClose(webSocket, event);
                        }, delay);
                    }
                })();
            }
            this._debug('Transport', this.getType(), 'waiting at most', delay, 'ms for messages', messageIds, 'maxNetworkDelay', maxDelay, ', timeouts:', _timeouts);
        }
    
        function _send(webSocket, envelope, metaConnect) {
            try {
                if (webSocket === null) {
                    _websocketConnect.call(this);
                } else {
                    _webSocketSend.call(this, webSocket, envelope, metaConnect);
                }
            } catch (x) {
                this.setTimeout(function() {
                    envelope.onFailure(webSocket, envelope.messages, {
                        exception: x
                    });
                }, 0);
            }
        }
        _self.onOpen = function(webSocket) {
            this._debug('Transport', this.getType(), 'opened', webSocket);
            _webSocket = webSocket;
            _webSocketConnected = true;
            this._debug('Sending pending messages', _envelopes);
            for (var key in _envelopes) {
                var element = _envelopes[key];
                var envelope = element[0];
                var metaConnect = element[1];
                _successCallback = envelope.onSuccess;
                _webSocketSend.call(this, webSocket, envelope, metaConnect);
            }
        };
        _self.onMessage = function(webSocket, wsMessage) {
            this._debug('Transport', this.getType(), 'received websocket message', wsMessage, webSocket);
            var close = false;
            var messages = this.convertToMessages(wsMessage.data);
            var messageIds = [];
            for (var i = 0; i < messages.length; ++i) {
                var message = messages[i];
                if (/^\/meta\//.test(message.channel) || message.successful !== undefined) {
                    if (message.id) {
                        messageIds.push(message.id);
                        var timeout = _timeouts[message.id];
                        if (timeout) {
                            this.clearTimeout(timeout);
                            delete _timeouts[message.id];
                            this._debug('Transport', this.getType(), 'removed timeout for message', message.id, ', timeouts', _timeouts);
                        }
                    }
                }
                if ('/meta/connect' === message.channel) {
                    _connected = false;
                }
                if ('/meta/disconnect' === message.channel && !_connected) {
                    close = true;
                }
            }
            var removed = false;
            for (var j = 0; j < messageIds.length; ++j) {
                var id = messageIds[j];
                for (var key in _envelopes) {
                    var ids = key.split(',');
                    var index = org.cometd.Utils.inArray(id, ids);
                    if (index >= 0) {
                        removed = true;
                        ids.splice(index, 1);
                        var envelope = _envelopes[key][0];
                        var metaConnect = _envelopes[key][1];
                        delete _envelopes[key];
                        if (ids.length > 0) {
                            _envelopes[ids.join(',')] = [envelope, metaConnect];
                        }
                        break;
                    }
                }
            }
            if (removed) {
                this._debug('Transport', this.getType(), 'removed envelope, envelopes', _envelopes);
            }
            _successCallback.call(this, messages);
            if (close) {
                this.webSocketClose(webSocket, 1000, 'Disconnect');
            }
        };
        _self.onClose = function(webSocket, event) {
            this._debug('Transport', this.getType(), 'closed', webSocket, event);
            _webSocketSupported = _stickyReconnect && _webSocketConnected;
            for (var id in _timeouts) {
                this.clearTimeout(_timeouts[id]);
            }
            _timeouts = {};
            for (var key in _envelopes) {
                var envelope = _envelopes[key][0];
                var metaConnect = _envelopes[key][1];
                if (metaConnect) {
                    _connected = false;
                }
                envelope.onFailure(webSocket, envelope.messages, {
                    websocketCode: event.code,
                    reason: event.reason
                });
            }
            _envelopes = {};
            _webSocket = null;
        };
        _self.registered = function(type, cometd) {
            _super.registered(type, cometd);
            _cometd = cometd;
        };
        _self.accept = function(version, crossDomain, url) {
            return _webSocketSupported && !!org.cometd.WebSocket && _cometd.websocketEnabled !== false;
        };
        _self.send = function(envelope, metaConnect) {
            this._debug('Transport', this.getType(), 'sending', envelope, 'metaConnect =', metaConnect);
            var messageIds = [];
            for (var i = 0; i < envelope.messages.length; ++i) {
                var message = envelope.messages[i];
                if (message.id) {
                    messageIds.push(message.id);
                }
            }
            _envelopes[messageIds.join(',')] = [envelope, metaConnect];
            this._debug('Transport', this.getType(), 'stored envelope, envelopes', _envelopes);
            _send.call(this, _webSocket, envelope, metaConnect);
        };
        _self.webSocketClose = function(webSocket, code, reason) {
            try {
                webSocket.close(code, reason);
            } catch (x) {
                this._debug(x);
            }
        };
        _self.abort = function() {
            _super.abort();
            if (_webSocket) {
                var event = {
                    code: 1001,
                    reason: 'Abort'
                };
                this.webSocketClose(_webSocket, event.code, event.reason);
                this.onClose(_webSocket, event);
            }
            this.reset();
        };
        return _self;
    };
    org.cometd.Cometd = function(name) {
        var _cometd = this;
        var _name = name || 'default';
        var _crossDomain = false;
        var _transports = new org.cometd.TransportRegistry();
        var _transport;
        var _status = 'disconnected';
        var _messageId = 0;
        var _clientId = null;
        var _batch = 0;
        var _messageQueue = [];
        var _internalBatch = false;
        var _listeners = {};
        var _backoff = 0;
        var _scheduledSend = null;
        var _extensions = [];
        var _advice = {};
        var _handshakeProps;
        var _handshakeCallback;
        var _callbacks = {};
        var _reestablish = false;
        var _connected = false;
        var _config = {
            protocol: null,
            stickyReconnect: true,
            connectTimeout: 0,
            maxConnections: 2,
            backoffIncrement: 1000,
            maxBackoff: 60000,
            logLevel: 'info',
            reverseIncomingExtensions: true,
            maxNetworkDelay: 10000,
            requestHeaders: {},
            appendMessageTypeToURL: true,
            autoBatch: false,
            advice: {
                timeout: 60000,
                interval: 0,
                reconnect: 'retry'
            }
        };
    
        function _fieldValue(object, name) {
            try {
                return object[name];
            } catch (x) {
                return undefined;
            }
        }
        this._mixin = function(deep, target, objects) {
            var result = target || {};
            for (var i = 2; i < arguments.length; ++i) {
                var object = arguments[i];
                if (object === undefined || object === null) {
                    continue;
                }
                for (var propName in object) {
                    var prop = _fieldValue(object, propName);
                    var targ = _fieldValue(result, propName);
                    if (prop === target) {
                        continue;
                    }
                    if (prop === undefined) {
                        continue;
                    }
                    if (deep && typeof prop === 'object' && prop !== null) {
                        if (prop instanceof Array) {
                            result[propName] = this._mixin(deep, targ instanceof Array ? targ : [], prop);
                        } else {
                            var source = typeof targ === 'object' && !(targ instanceof Array) ? targ : {};
                            result[propName] = this._mixin(deep, source, prop);
                        }
                    } else {
                        result[propName] = prop;
                    }
                }
            }
            return result;
        };
    
        function _isString(value) {
            return org.cometd.Utils.isString(value);
        }
    
        function _isFunction(value) {
            if (value === undefined || value === null) {
                return false;
            }
            return typeof value === 'function';
        }
    
        function _log(level, args) {
            if (window.console) {
                var logger = window.console[level];
                if (_isFunction(logger)) {
                    logger.apply(window.console, args);
                }
            }
        }
        this._warn = function() {
            _log('warn', arguments);
        };
        this._info = function() {
            if (_config.logLevel !== 'warn') {
                _log('info', arguments);
            }
        };
        this._debug = function() {
            if (_config.logLevel === 'debug') {
                _log('debug', arguments);
            }
        };
        this._isCrossDomain = function(hostAndPort) {
            return hostAndPort && hostAndPort !== window.location.host;
        };
    
        function _configure(configuration) {
            _cometd._debug('Configuring cometd object with', configuration);
            if (_isString(configuration)) {
                configuration = {
                    url: configuration
                };
            }
            if (!configuration) {
                configuration = {};
            }
            _config = _cometd._mixin(false, _config, configuration);
            var url = _cometd.getURL();
            if (!url) {
                throw 'Missing required configuration parameter \'url\' specifying the Bayeux server URL';
            }
            var urlParts = /(^https?:\/\/)?(((\[[^\]]+\])|([^:\/\?#]+))(:(\d+))?)?([^\?#]*)(.*)?/.exec(url);
            var hostAndPort = urlParts[2];
            var uri = urlParts[8];
            var afterURI = urlParts[9];
            _crossDomain = _cometd._isCrossDomain(hostAndPort);
            if (_config.appendMessageTypeToURL) {
                if (afterURI !== undefined && afterURI.length > 0) {
                    _cometd._info('Appending message type to URI ' + uri + afterURI + ' is not supported, disabling \'appendMessageTypeToURL\' configuration');
                    _config.appendMessageTypeToURL = false;
                } else {
                    var uriSegments = uri.split('/');
                    var lastSegmentIndex = uriSegments.length - 1;
                    if (uri.match(/\/$/)) {
                        lastSegmentIndex -= 1;
                    }
                    if (uriSegments[lastSegmentIndex].indexOf('.') >= 0) {
                        _cometd._info('Appending message type to URI ' + uri + ' is not supported, disabling \'appendMessageTypeToURL\' configuration');
                        _config.appendMessageTypeToURL = false;
                    }
                }
            }
        }
    
        function _removeListener(subscription) {
            if (subscription) {
                var subscriptions = _listeners[subscription.channel];
                if (subscriptions && subscriptions[subscription.id]) {
                    delete subscriptions[subscription.id];
                    _cometd._debug('Removed', subscription.listener ? 'listener' : 'subscription', subscription);
                }
            }
        }
    
        function _removeSubscription(subscription) {
            if (subscription && !subscription.listener) {
                _removeListener(subscription);
            }
        }
    
        function _clearSubscriptions() {
            for (var channel in _listeners) {
                var subscriptions = _listeners[channel];
                if (subscriptions) {
                    for (var i = 0; i < subscriptions.length; ++i) {
                        _removeSubscription(subscriptions[i]);
                    }
                }
            }
        }
    
        function _setStatus(newStatus) {
            if (_status !== newStatus) {
                _cometd._debug('Status', _status, '->', newStatus);
                _status = newStatus;
            }
        }
    
        function _isDisconnected() {
            return _status === 'disconnecting' || _status === 'disconnected';
        }
    
        function _nextMessageId() {
            return ++_messageId;
        }
    
        function _applyExtension(scope, callback, name, message, outgoing) {
            try {
                return callback.call(scope, message);
            } catch (x) {
                _cometd._debug('Exception during execution of extension', name, x);
                var exceptionCallback = _cometd.onExtensionException;
                if (_isFunction(exceptionCallback)) {
                    _cometd._debug('Invoking extension exception callback', name, x);
                    try {
                        exceptionCallback.call(_cometd, x, name, outgoing, message);
                    } catch (xx) {
                        _cometd._info('Exception during execution of exception callback in extension', name, xx);
                    }
                }
                return message;
            }
        }
    
        function _applyIncomingExtensions(message) {
            for (var i = 0; i < _extensions.length; ++i) {
                if (message === undefined || message === null) {
                    break;
                }
                var index = _config.reverseIncomingExtensions ? _extensions.length - 1 - i : i;
                var extension = _extensions[index];
                var callback = extension.extension.incoming;
                if (_isFunction(callback)) {
                    var result = _applyExtension(extension.extension, callback, extension.name, message, false);
                    message = result === undefined ? message : result;
                }
            }
            return message;
        }
    
        function _applyOutgoingExtensions(message) {
            for (var i = 0; i < _extensions.length; ++i) {
                if (message === undefined || message === null) {
                    break;
                }
                var extension = _extensions[i];
                var callback = extension.extension.outgoing;
                if (_isFunction(callback)) {
                    var result = _applyExtension(extension.extension, callback, extension.name, message, true);
                    message = result === undefined ? message : result;
                }
            }
            return message;
        }
    
        function _notify(channel, message) {
            var subscriptions = _listeners[channel];
            if (subscriptions && subscriptions.length > 0) {
                for (var i = 0; i < subscriptions.length; ++i) {
                    var subscription = subscriptions[i];
                    if (subscription) {
                        try {
                            subscription.callback.call(subscription.scope, message);
                        } catch (x) {
                            _cometd._debug('Exception during notification', subscription, message, x);
                            var listenerCallback = _cometd.onListenerException;
                            if (_isFunction(listenerCallback)) {
                                _cometd._debug('Invoking listener exception callback', subscription, x);
                                try {
                                    listenerCallback.call(_cometd, x, subscription, subscription.listener, message);
                                } catch (xx) {
                                    _cometd._info('Exception during execution of listener callback', subscription, xx);
                                }
                            }
                        }
                    }
                }
            }
        }
    
        function _notifyListeners(channel, message) {
            _notify(channel, message);
            var channelParts = channel.split('/');
            var last = channelParts.length - 1;
            for (var i = last; i > 0; --i) {
                var channelPart = channelParts.slice(0, i).join('/') + '/*';
                if (i === last) {
                    _notify(channelPart, message);
                }
                channelPart += '*';
                _notify(channelPart, message);
            }
        }
    
        function _cancelDelayedSend() {
            if (_scheduledSend !== null) {
                org.cometd.Utils.clearTimeout(_scheduledSend);
            }
            _scheduledSend = null;
        }
    
        function _delayedSend(operation) {
            _cancelDelayedSend();
            var delay = _advice.interval + _backoff;
            _cometd._debug('Function scheduled in', delay, 'ms, interval =', _advice.interval, 'backoff =', _backoff, operation);
            _scheduledSend = org.cometd.Utils.setTimeout(_cometd, operation, delay);
        }
        var _handleMessages;
        var _handleFailure;
    
        function _send(sync, messages, longpoll, extraPath) {
            for (var i = 0; i < messages.length; ++i) {
                var message = messages[i];
                var messageId = '' + _nextMessageId();
                message.id = messageId;
                if (_clientId) {
                    message.clientId = _clientId;
                }
                var callback = undefined;
                if (_isFunction(message._callback)) {
                    callback = message._callback;
                    delete message._callback;
                }
                message = _applyOutgoingExtensions(message);
                if (message !== undefined && message !== null) {
                    message.id = messageId;
                    messages[i] = message;
                    if (callback) {
                        _callbacks[messageId] = callback;
                    }
                } else {
                    messages.splice(i--, 1);
                }
            }
            if (messages.length === 0) {
                return;
            }
            var url = _cometd.getURL();
            if (_config.appendMessageTypeToURL) {
                if (!url.match(/\/$/)) {
                    url = url + '/';
                }
                if (extraPath) {
                    url = url + extraPath;
                }
            }
            var envelope = {
                url: url,
                sync: sync,
                messages: messages,
                onSuccess: function(rcvdMessages) {
                    try {
                        _handleMessages.call(_cometd, rcvdMessages);
                    } catch (x) {
                        _cometd._debug('Exception during handling of messages', x);
                    }
                },
                onFailure: function(conduit, messages, failure) {
                    try {
                        failure.connectionType = _cometd.getTransport().getType();
                        _handleFailure.call(_cometd, conduit, messages, failure);
                    } catch (x) {
                        _cometd._debug('Exception during handling of failure', x);
                    }
                }
            };
            _cometd._debug('Send', envelope);
            _transport.send(envelope, longpoll);
        }
    
        function _queueSend(message) {
            if (_batch > 0 || _internalBatch === true) {
                _messageQueue.push(message);
            } else {
                _send(false, [message], false);
            }
        }
        this.send = _queueSend;
    
        function _resetBackoff() {
            _backoff = 0;
        }
    
        function _increaseBackoff() {
            if (_backoff < _config.maxBackoff) {
                _backoff += _config.backoffIncrement;
            }
        }
    
        function _startBatch() {
            ++_batch;
        }
    
        function _flushBatch() {
            var messages = _messageQueue;
            _messageQueue = [];
            if (messages.length > 0) {
                _send(false, messages, false);
            }
        }
    
        function _endBatch() {
            --_batch;
            if (_batch < 0) {
                throw 'Calls to startBatch() and endBatch() are not paired';
            }
            if (_batch === 0 && !_isDisconnected() && !_internalBatch) {
                _flushBatch();
            }
        }
    
        function _connect() {
            if (!_isDisconnected()) {
                var message = {
                    channel: '/meta/connect',
                    connectionType: _transport.getType()
                };
                if (!_connected) {
                    message.advice = {
                        timeout: 0
                    };
                }
                _setStatus('connecting');
                _cometd._debug('Connect sent', message);
                _send(false, [message], true, 'connect');
                _setStatus('connected');
            }
        }
    
        function _delayedConnect() {
            _setStatus('connecting');
            _delayedSend(function() {
                _connect();
            });
        }
    
        function _updateAdvice(newAdvice) {
            if (newAdvice) {
                _advice = _cometd._mixin(false, {}, _config.advice, newAdvice);
                _cometd._debug('New advice', _advice);
            }
        }
    
        function _disconnect(abort) {
            _cancelDelayedSend();
            if (abort) {
                _transport.abort();
            }
            _clientId = null;
            _setStatus('disconnected');
            _batch = 0;
            _resetBackoff();
            _transport = null;
            if (_messageQueue.length > 0) {
                _handleFailure.call(_cometd, undefined, _messageQueue, {
                    reason: 'Disconnected'
                });
                _messageQueue = [];
            }
        }
    
        function _notifyTransportFailure(oldTransport, newTransport, failure) {
            var callback = _cometd.onTransportFailure;
            if (_isFunction(callback)) {
                _cometd._debug('Invoking transport failure callback', oldTransport, newTransport, failure);
                try {
                    callback.call(_cometd, oldTransport, newTransport, failure);
                } catch (x) {
                    _cometd._info('Exception during execution of transport failure callback', x);
                }
            }
        }
    
        function _handshake(handshakeProps, handshakeCallback) {
            if (_isFunction(handshakeProps)) {
                handshakeCallback = handshakeProps;
                handshakeProps = undefined;
            }
            _clientId = null;
            _clearSubscriptions();
            if (_isDisconnected()) {
                _transports.reset();
                _updateAdvice(_config.advice);
            } else {
                _updateAdvice(_cometd._mixin(false, _advice, {
                    reconnect: 'retry'
                }));
            }
            _batch = 0;
            _internalBatch = true;
            _handshakeProps = handshakeProps;
            _handshakeCallback = handshakeCallback;
            var version = '1.0';
            var url = _cometd.getURL();
            var transportTypes = _transports.findTransportTypes(version, _crossDomain, url);
            var bayeuxMessage = {
                version: version,
                minimumVersion: version,
                channel: '/meta/handshake',
                supportedConnectionTypes: transportTypes,
                _callback: handshakeCallback,
                advice: {
                    timeout: _advice.timeout,
                    interval: _advice.interval
                }
            };
            var message = _cometd._mixin(false, {}, _handshakeProps, bayeuxMessage);
            if (!_transport) {
                _transport = _transports.negotiateTransport(transportTypes, version, _crossDomain, url);
                if (!_transport) {
                    var failure = 'Could not find initial transport among: ' + _transports.getTransportTypes();
                    _cometd._warn(failure);
                    throw failure;
                }
            }
            _cometd._debug('Initial transport is', _transport.getType());
            _setStatus('handshaking');
            _cometd._debug('Handshake sent', message);
            _send(false, [message], false, 'handshake');
        }
    
        function _delayedHandshake() {
            _setStatus('handshaking');
            _internalBatch = true;
            _delayedSend(function() {
                _handshake(_handshakeProps, _handshakeCallback);
            });
        }
    
        function _handleCallback(message) {
            var callback = _callbacks[message.id];
            if (_isFunction(callback)) {
                delete _callbacks[message.id];
                callback.call(_cometd, message);
            }
        }
    
        function _failHandshake(message) {
            _handleCallback(message);
            _notifyListeners('/meta/handshake', message);
            _notifyListeners('/meta/unsuccessful', message);
            var retry = !_isDisconnected() && _advice.reconnect !== 'none';
            if (retry) {
                _increaseBackoff();
                _delayedHandshake();
            } else {
                _disconnect(false);
            }
        }
    
        function _handshakeResponse(message) {
            if (message.successful) {
                _clientId = message.clientId;
                var url = _cometd.getURL();
                var newTransport = _transports.negotiateTransport(message.supportedConnectionTypes, message.version, _crossDomain, url);
                if (newTransport === null) {
                    var failure = 'Could not negotiate transport with server; client=[' +
                        _transports.findTransportTypes(message.version, _crossDomain, url) +
                        '], server=[' + message.supportedConnectionTypes + ']';
                    var oldTransport = _cometd.getTransport();
                    _notifyTransportFailure(oldTransport.getType(), null, {
                        reason: failure,
                        connectionType: oldTransport.getType(),
                        transport: oldTransport
                    });
                    _cometd._warn(failure);
                    _transport.reset();
                    _failHandshake(message);
                    return;
                } else if (_transport !== newTransport) {
                    _cometd._debug('Transport', _transport.getType(), '->', newTransport.getType());
                    _transport = newTransport;
                }
                _internalBatch = false;
                _flushBatch();
                message.reestablish = _reestablish;
                _reestablish = true;
                _handleCallback(message);
                _notifyListeners('/meta/handshake', message);
                var action = _isDisconnected() ? 'none' : _advice.reconnect;
                switch (action) {
                    case 'retry':
                        _resetBackoff();
                        _delayedConnect();
                        break;
                    case 'none':
                        _disconnect(false);
                        break;
                    default:
                        throw 'Unrecognized advice action ' + action;
                }
            } else {
                _failHandshake(message);
            }
        }
    
        function _handshakeFailure(message) {
            var version = '1.0';
            var url = _cometd.getURL();
            var oldTransport = _cometd.getTransport();
            var transportTypes = _transports.findTransportTypes(version, _crossDomain, url);
            var newTransport = _transports.negotiateTransport(transportTypes, version, _crossDomain, url);
            if (!newTransport) {
                _notifyTransportFailure(oldTransport.getType(), null, message.failure);
                _cometd._warn('Could not negotiate transport; client=[' + transportTypes + ']');
                _transport.reset();
                _failHandshake(message);
            } else {
                _cometd._debug('Transport', oldTransport.getType(), '->', newTransport.getType());
                _notifyTransportFailure(oldTransport.getType(), newTransport.getType(), message.failure);
                _failHandshake(message);
                _transport = newTransport;
            }
        }
    
        function _failConnect(message) {
            _notifyListeners('/meta/connect', message);
            _notifyListeners('/meta/unsuccessful', message);
            var action = _isDisconnected() ? 'none' : _advice.reconnect;
            switch (action) {
                case 'retry':
                    _delayedConnect();
                    _increaseBackoff();
                    break;
                case 'handshake':
                    _transports.reset();
                    _resetBackoff();
                    _delayedHandshake();
                    break;
                case 'none':
                    _disconnect(false);
                    break;
                default:
                    throw 'Unrecognized advice action' + action;
            }
        }
    
        function _connectResponse(message) {
            _connected = message.successful;
            if (_connected) {
                _notifyListeners('/meta/connect', message);
                var action = _isDisconnected() ? 'none' : _advice.reconnect;
                switch (action) {
                    case 'retry':
                        _resetBackoff();
                        _delayedConnect();
                        break;
                    case 'none':
                        _disconnect(false);
                        break;
                    default:
                        throw 'Unrecognized advice action ' + action;
                }
            } else {
                _failConnect(message);
            }
        }
    
        function _connectFailure(message) {
            _connected = false;
            _failConnect(message);
        }
    
        function _failDisconnect(message) {
            _disconnect(true);
            _handleCallback(message);
            _notifyListeners('/meta/disconnect', message);
            _notifyListeners('/meta/unsuccessful', message);
        }
    
        function _disconnectResponse(message) {
            if (message.successful) {
                _disconnect(false);
                _handleCallback(message);
                _notifyListeners('/meta/disconnect', message);
            } else {
                _failDisconnect(message);
            }
        }
    
        function _disconnectFailure(message) {
            _failDisconnect(message);
        }
    
        function _failSubscribe(message) {
            var subscriptions = _listeners[message.subscription];
            if (subscriptions) {
                for (var i = subscriptions.length - 1; i >= 0; --i) {
                    var subscription = subscriptions[i];
                    if (subscription && !subscription.listener) {
                        delete subscriptions[i];
                        _cometd._debug('Removed failed subscription', subscription);
                        break;
                    }
                }
            }
            _handleCallback(message);
            _notifyListeners('/meta/subscribe', message);
            _notifyListeners('/meta/unsuccessful', message);
        }
    
        function _subscribeResponse(message) {
            if (message.successful) {
                _handleCallback(message);
                _notifyListeners('/meta/subscribe', message);
            } else {
                _failSubscribe(message);
            }
        }
    
        function _subscribeFailure(message) {
            _failSubscribe(message);
        }
    
        function _failUnsubscribe(message) {
            _handleCallback(message);
            _notifyListeners('/meta/unsubscribe', message);
            _notifyListeners('/meta/unsuccessful', message);
        }
    
        function _unsubscribeResponse(message) {
            if (message.successful) {
                _handleCallback(message);
                _notifyListeners('/meta/unsubscribe', message);
            } else {
                _failUnsubscribe(message);
            }
        }
    
        function _unsubscribeFailure(message) {
            _failUnsubscribe(message);
        }
    
        function _failMessage(message) {
            _handleCallback(message);
            _notifyListeners('/meta/publish', message);
            _notifyListeners('/meta/unsuccessful', message);
        }
    
        function _messageResponse(message) {
            if (message.successful === undefined) {
                if (message.data !== undefined) {
                    _notifyListeners(message.channel, message);
                } else {
                    _cometd._warn('Unknown Bayeux Message', message);
                }
            } else {
                if (message.successful) {
                    _handleCallback(message);
                    _notifyListeners('/meta/publish', message);
                } else {
                    _failMessage(message);
                }
            }
        }
    
        function _messageFailure(failure) {
            _failMessage(failure);
        }
    
        function _receive(message) {
            message = _applyIncomingExtensions(message);
            if (message === undefined || message === null) {
                return;
            }
            _updateAdvice(message.advice);
            var channel = message.channel;
            switch (channel) {
                case '/meta/handshake':
                    _handshakeResponse(message);
                    break;
                case '/meta/connect':
                    _connectResponse(message);
                    break;
                case '/meta/disconnect':
                    _disconnectResponse(message);
                    break;
                case '/meta/subscribe':
                    _subscribeResponse(message);
                    break;
                case '/meta/unsubscribe':
                    _unsubscribeResponse(message);
                    break;
                default:
                    _messageResponse(message);
                    break;
            }
        }
        this.receive = _receive;
        _handleMessages = function(rcvdMessages) {
            _cometd._debug('Received', rcvdMessages);
            for (var i = 0; i < rcvdMessages.length; ++i) {
                var message = rcvdMessages[i];
                _receive(message);
            }
        };
        _handleFailure = function(conduit, messages, failure) {
            _cometd._debug('handleFailure', conduit, messages, failure);
            failure.transport = conduit;
            for (var i = 0; i < messages.length; ++i) {
                var message = messages[i];
                var failureMessage = {
                    id: message.id,
                    successful: false,
                    channel: message.channel,
                    failure: failure
                };
                failure.message = message;
                switch (message.channel) {
                    case '/meta/handshake':
                        _handshakeFailure(failureMessage);
                        break;
                    case '/meta/connect':
                        _connectFailure(failureMessage);
                        break;
                    case '/meta/disconnect':
                        _disconnectFailure(failureMessage);
                        break;
                    case '/meta/subscribe':
                        failureMessage.subscription = message.subscription;
                        _subscribeFailure(failureMessage);
                        break;
                    case '/meta/unsubscribe':
                        failureMessage.subscription = message.subscription;
                        _unsubscribeFailure(failureMessage);
                        break;
                    default:
                        _messageFailure(failureMessage);
                        break;
                }
            }
        };
    
        function _hasSubscriptions(channel) {
            var subscriptions = _listeners[channel];
            if (subscriptions) {
                for (var i = 0; i < subscriptions.length; ++i) {
                    if (subscriptions[i]) {
                        return true;
                    }
                }
            }
            return false;
        }
    
        function _resolveScopedCallback(scope, callback) {
            var delegate = {
                scope: scope,
                method: callback
            };
            if (_isFunction(scope)) {
                delegate.scope = undefined;
                delegate.method = scope;
            } else {
                if (_isString(callback)) {
                    if (!scope) {
                        throw 'Invalid scope ' + scope;
                    }
                    delegate.method = scope[callback];
                    if (!_isFunction(delegate.method)) {
                        throw 'Invalid callback ' + callback + ' for scope ' + scope;
                    }
                } else if (!_isFunction(callback)) {
                    throw 'Invalid callback ' + callback;
                }
            }
            return delegate;
        }
    
        function _addListener(channel, scope, callback, isListener) {
            var delegate = _resolveScopedCallback(scope, callback);
            _cometd._debug('Adding', isListener ? 'listener' : 'subscription', 'on', channel, 'with scope', delegate.scope, 'and callback', delegate.method);
            var subscription = {
                channel: channel,
                scope: delegate.scope,
                callback: delegate.method,
                listener: isListener
            };
            var subscriptions = _listeners[channel];
            if (!subscriptions) {
                subscriptions = [];
                _listeners[channel] = subscriptions;
            }
            subscription.id = subscriptions.push(subscription) - 1;
            _cometd._debug('Added', isListener ? 'listener' : 'subscription', subscription);
            subscription[0] = channel;
            subscription[1] = subscription.id;
            return subscription;
        }
        this.registerTransport = function(type, transport, index) {
            var result = _transports.add(type, transport, index);
            if (result) {
                this._debug('Registered transport', type);
                if (_isFunction(transport.registered)) {
                    transport.registered(type, this);
                }
            }
            return result;
        };
        this.getTransportTypes = function() {
            return _transports.getTransportTypes();
        };
        this.unregisterTransport = function(type) {
            var transport = _transports.remove(type);
            if (transport !== null) {
                this._debug('Unregistered transport', type);
                if (_isFunction(transport.unregistered)) {
                    transport.unregistered();
                }
            }
            return transport;
        };
        this.unregisterTransports = function() {
            _transports.clear();
        };
        this.findTransport = function(name) {
            return _transports.find(name);
        };
        this.configure = function(configuration) {
            _configure.call(this, configuration);
        };
        this.init = function(configuration, handshakeProps) {
            this.configure(configuration);
            this.handshake(handshakeProps);
        };
        this.handshake = function(handshakeProps, handshakeCallback) {
            _setStatus('disconnected');
            _reestablish = false;
            _handshake(handshakeProps, handshakeCallback);
        };
        this.disconnect = function(sync, disconnectProps, disconnectCallback) {
            if (_isDisconnected()) {
                return;
            }
            if (typeof sync !== 'boolean') {
                disconnectCallback = disconnectProps;
                disconnectProps = sync;
                sync = false;
            }
            if (_isFunction(disconnectProps)) {
                disconnectCallback = disconnectProps;
                disconnectProps = undefined;
            }
            var bayeuxMessage = {
                channel: '/meta/disconnect',
                _callback: disconnectCallback
            };
            var message = this._mixin(false, {}, disconnectProps, bayeuxMessage);
            _setStatus('disconnecting');
            _send(sync === true, [message], false, 'disconnect');
        };
        this.startBatch = function() {
            _startBatch();
        };
        this.endBatch = function() {
            _endBatch();
        };
        this.batch = function(scope, callback) {
            var delegate = _resolveScopedCallback(scope, callback);
            this.startBatch();
            try {
                delegate.method.call(delegate.scope);
                this.endBatch();
            } catch (x) {
                this._info('Exception during execution of batch', x);
                this.endBatch();
                throw x;
            }
        };
        this.addListener = function(channel, scope, callback) {
            if (arguments.length < 2) {
                throw 'Illegal arguments number: required 2, got ' + arguments.length;
            }
            if (!_isString(channel)) {
                throw 'Illegal argument type: channel must be a string';
            }
            return _addListener(channel, scope, callback, true);
        };
        this.removeListener = function(subscription) {
            if (!subscription || !subscription.channel || !("id" in subscription)) {
                throw 'Invalid argument: expected subscription, not ' + subscription;
            }
            _removeListener(subscription);
        };
        this.clearListeners = function() {
            _listeners = {};
        };
        this.subscribe = function(channel, scope, callback, subscribeProps, subscribeCallback) {
            if (arguments.length < 2) {
                throw 'Illegal arguments number: required 2, got ' + arguments.length;
            }
            if (!_isString(channel)) {
                throw 'Illegal argument type: channel must be a string';
            }
            if (_isDisconnected()) {
                throw 'Illegal state: already disconnected';
            }
            if (_isFunction(scope)) {
                subscribeCallback = subscribeProps;
                subscribeProps = callback;
                callback = scope;
                scope = undefined;
            }
            if (_isFunction(subscribeProps)) {
                subscribeCallback = subscribeProps;
                subscribeProps = undefined;
            }
            var send = !_hasSubscriptions(channel);
            var subscription = _addListener(channel, scope, callback, false);
            if (send) {
                var bayeuxMessage = {
                    channel: '/meta/subscribe',
                    subscription: channel,
                    _callback: subscribeCallback
                };
                var message = this._mixin(false, {}, subscribeProps, bayeuxMessage);
                _queueSend(message);
            }
            return subscription;
        };
        this.unsubscribe = function(subscription, unsubscribeProps, unsubscribeCallback) {
            if (arguments.length < 1) {
                throw 'Illegal arguments number: required 1, got ' + arguments.length;
            }
            if (_isDisconnected()) {
                throw 'Illegal state: already disconnected';
            }
            if (_isFunction(unsubscribeProps)) {
                unsubscribeCallback = unsubscribeProps;
                unsubscribeProps = undefined;
            }
            this.removeListener(subscription);
            var channel = subscription.channel;
            if (!_hasSubscriptions(channel)) {
                var bayeuxMessage = {
                    channel: '/meta/unsubscribe',
                    subscription: channel,
                    _callback: unsubscribeCallback
                };
                var message = this._mixin(false, {}, unsubscribeProps, bayeuxMessage);
                _queueSend(message);
            }
        };
        this.resubscribe = function(subscription, subscribeProps) {
            _removeSubscription(subscription);
            if (subscription) {
                return this.subscribe(subscription.channel, subscription.scope, subscription.callback, subscribeProps);
            }
            return undefined;
        };
        this.clearSubscriptions = function() {
            _clearSubscriptions();
        };
        this.publish = function(channel, content, publishProps, publishCallback) {
            if (arguments.length < 1) {
                throw 'Illegal arguments number: required 1, got ' + arguments.length;
            }
            if (!_isString(channel)) {
                throw 'Illegal argument type: channel must be a string';
            }
            if (/^\/meta\//.test(channel)) {
                throw 'Illegal argument: cannot publish to meta channels';
            }
            if (_isDisconnected()) {
                throw 'Illegal state: already disconnected';
            }
            if (_isFunction(content)) {
                publishCallback = content;
                content = publishProps = {};
            } else if (_isFunction(publishProps)) {
                publishCallback = publishProps;
                publishProps = {};
            }
            var bayeuxMessage = {
                channel: channel,
                data: content,
                _callback: publishCallback
            };
            var message = this._mixin(false, {}, publishProps, bayeuxMessage);
            _queueSend(message);
        };
        this.getStatus = function() {
            return _status;
        };
        this.isDisconnected = _isDisconnected;
        this.setBackoffIncrement = function(period) {
            _config.backoffIncrement = period;
        };
        this.getBackoffIncrement = function() {
            return _config.backoffIncrement;
        };
        this.getBackoffPeriod = function() {
            return _backoff;
        };
        this.setLogLevel = function(level) {
            _config.logLevel = level;
        };
        this.registerExtension = function(name, extension) {
            if (arguments.length < 2) {
                throw 'Illegal arguments number: required 2, got ' + arguments.length;
            }
            if (!_isString(name)) {
                throw 'Illegal argument type: extension name must be a string';
            }
            var existing = false;
            for (var i = 0; i < _extensions.length; ++i) {
                var existingExtension = _extensions[i];
                if (existingExtension.name === name) {
                    existing = true;
                    break;
                }
            }
            if (!existing) {
                _extensions.push({
                    name: name,
                    extension: extension
                });
                this._debug('Registered extension', name);
                if (_isFunction(extension.registered)) {
                    extension.registered(name, this);
                }
                return true;
            } else {
                this._info('Could not register extension with name', name, 'since another extension with the same name already exists');
                return false;
            }
        };
        this.unregisterExtension = function(name) {
            if (!_isString(name)) {
                throw 'Illegal argument type: extension name must be a string';
            }
            var unregistered = false;
            for (var i = 0; i < _extensions.length; ++i) {
                var extension = _extensions[i];
                if (extension.name === name) {
                    _extensions.splice(i, 1);
                    unregistered = true;
                    this._debug('Unregistered extension', name);
                    var ext = extension.extension;
                    if (_isFunction(ext.unregistered)) {
                        ext.unregistered();
                    }
                    break;
                }
            }
            return unregistered;
        };
        this.getExtension = function(name) {
            for (var i = 0; i < _extensions.length; ++i) {
                var extension = _extensions[i];
                if (extension.name === name) {
                    return extension.extension;
                }
            }
            return null;
        };
        this.getName = function() {
            return _name;
        };
        this.getClientId = function() {
            return _clientId;
        };
        this.getURL = function() {
            if (_transport && typeof _config.urls === 'object') {
                var url = _config.urls[_transport.getType()];
                if (url) {
                    return url;
                }
            }
            return _config.url;
        };
        this.getTransport = function() {
            return _transport;
        };
        this.getConfiguration = function() {
            return this._mixin(true, {}, _config);
        };
        this.getAdvice = function() {
            return this._mixin(true, {}, _advice);
        };
        org.cometd.WebSocket = window.WebSocket;
        if (!org.cometd.WebSocket) {
            org.cometd.WebSocket = window.MozWebSocket;
        }
    };
    if (typeof define === 'function' && define.amd) {
        define(function() {
            return org.cometd;
        });
    };
    /*! RESOURCE: /scripts/thirdparty/cometd/jquery/jquery.cometd.js */
    (function() {
        function bind($, org_cometd) {
            org_cometd.JSON.toJSON = (window.JSON && JSON.stringify) || (window.jaredJSON && window.jaredJSON.stringify);
            org_cometd.JSON.fromJSON = (window.JSON && JSON.parse) || (window.jaredJSON && window.jaredJSON.parse);
    
            function _setHeaders(xhr, headers) {
                if (headers) {
                    for (var headerName in headers) {
                        if (headerName.toLowerCase() === 'content-type') {
                            continue;
                        }
                        xhr.setRequestHeader(headerName, headers[headerName]);
                    }
                }
            }
    
            function LongPollingTransport() {
                var _super = new org_cometd.LongPollingTransport();
                var that = org_cometd.Transport.derive(_super);
                that.xhrSend = function(packet) {
                    return $.ajax({
                        url: packet.url,
                        async: packet.sync !== true,
                        type: 'POST',
                        contentType: 'application/json;charset=UTF-8',
                        data: packet.body,
                        xhrFields: {
                            withCredentials: true
                        },
                        beforeSend: function(xhr) {
                            _setHeaders(xhr, packet.headers);
                            return true;
                        },
                        success: packet.onSuccess,
                        error: function(xhr, reason, exception) {
                            packet.onError(reason, exception);
                        }
                    });
                };
                return that;
            }
    
            function CallbackPollingTransport() {
                var _super = new org_cometd.CallbackPollingTransport();
                var that = org_cometd.Transport.derive(_super);
                that.jsonpSend = function(packet) {
                    $.ajax({
                        url: packet.url,
                        async: packet.sync !== true,
                        type: 'GET',
                        dataType: 'jsonp',
                        jsonp: 'jsonp',
                        data: {
                            message: packet.body
                        },
                        beforeSend: function(xhr) {
                            _setHeaders(xhr, packet.headers);
                            return true;
                        },
                        success: packet.onSuccess,
                        error: function(xhr, reason, exception) {
                            packet.onError(reason, exception);
                        }
                    });
                };
                return that;
            }
            $.Cometd = function(name) {
                var cometd = new org_cometd.Cometd(name);
                if (org_cometd.WebSocket) {
                    cometd.registerTransport('websocket', new org_cometd.WebSocketTransport());
                }
                cometd.registerTransport('long-polling', new LongPollingTransport());
                cometd.registerTransport('callback-polling', new CallbackPollingTransport());
                return cometd;
            };
            $.cometd = new $.Cometd();
            return $.cometd;
        }
        if (typeof define === 'function' && define.amd) {
            define(['jquery', 'org/cometd'], bind);
        } else {
            bind(window.jQuery1110 || window.Zepto, org.cometd);
        }
    })();;
    /*! RESOURCE: /scripts/amb_properties.js */
    var amb = amb || {
        properties: {
            servletURI: 'amb/',
            logLevel: 'info',
            loginWindow: 'true'
        }
    };;
    /*! RESOURCE: /scripts/amb.Logger.js */
    amb['Logger'] = function(callerType) {
        var _debugEnabled = amb['properties']['logLevel'] == 'debug';
    
        function print(message) {
            console.log(callerType + ' ' + message);
        }
        return {
            debug: function(message) {
                if (_debugEnabled)
                    print('[DEBUG] ' + message);
            },
            addInfoMessage: function(message) {
                print('[INFO] ' + message);
            },
            addErrorMessage: function(message) {
                print('[ERROR] ' + message);
            }
        }
    };;
    /*! RESOURCE: /scripts/amb.EventManager.js */
    amb.EventManager = function EventManager(events) {
        var _subscriptions = [];
        var _idCounter = 0;
    
        function _getSubscriptions(event) {
            var subscriptions = [];
            for (var i = 0; i < _subscriptions.length; i++) {
                if (_subscriptions[i].event == event)
                    subscriptions.push(_subscriptions[i]);
            }
            return subscriptions;
        }
        return {
            subscribe: function(event, callback) {
                var id = _idCounter++;
                _subscriptions.push({
                    event: event,
                    callback: callback,
                    id: id
                });
                return id;
            },
            unsubscribe: function(id) {
                for (var i = 0; i < _subscriptions.length; i++)
                    if (id == _subscriptions[i].id)
                        _subscriptions.splice(i, 1);
            },
            publish: function(event, args) {
                var subscriptions = _getSubscriptions(event);
                for (var i = 0; i < subscriptions.length; i++)
                    subscriptions[i].callback.apply(null, args);
            },
            getEvents: function() {
                return events;
            }
        }
    };;
    /*! RESOURCE: /scripts/amb.ServerConnection.js */
    amb.ServerConnection = function ServerConnection(cometd) {
        var connected = false;
        var disconnecting = false;
        var eventManager = new amb.EventManager({
            CONNECTION_INITIALIZED: 'connection.initialized',
            CONNECTION_OPENED: 'connection.opened',
            CONNECTION_CLOSED: 'connection.closed',
            CONNECTION_BROKEN: 'connection.broken',
            SESSION_LOGGED_IN: 'session.logged.in',
            SESSION_LOGGED_OUT: 'session.logged.out'
        });
        var state = "closed";
        var LOGGER = new amb.Logger('amb.ServerConnection');
        _initializeMetaChannelListeners();
        var loggedIn = true;
        var loginWindow = null;
        var loginWindowEnabled = amb.properties['loginWindow'] === 'true';
        var lastError = null;
        var errorMessages = {
            'UNKNOWN_CLIENT': '402::Unknown client'
        };
        var loginWindowOverride = false;
        var ambServerConnection = {};
        ambServerConnection.connect = function() {
            if (connected) {
                console.log(">>> connection exists, request satisfied");
                return;
            }
            LOGGER.debug('Connecting to glide amb server -> ' + amb['properties']['servletURI']);
            LOGGER.debug('Connecting to glide amb server -> ' + amb['properties']['servletURI']);
            cometd.configure({
                url: _getRelativePath(amb['properties']['servletURI']),
                logLevel: amb['properties']['logLevel']
            });
            cometd.handshake();
        };
        ambServerConnection.reload = function() {
            cometd.reload();
        };
        ambServerConnection.abort = function() {
            cometd.getTransport().abort();
        };
        ambServerConnection.disconnect = function() {
            LOGGER.debug('Disconnecting from glide amb server..');
            disconnecting = true;
            cometd.disconnect();
        };
    
        function _initializeMetaChannelListeners() {
            cometd.addListener('/meta/handshake', this, _metaHandshake);
            cometd.addListener('/meta/connect', this, _metaConnect);
        }
    
        function _metaHandshake(message) {
            setTimeout(function() {
                if (message['successful'])
                    _connectionInitialized();
            }, 0);
        }
    
        function _metaConnect(message) {
            if (disconnecting) {
                setTimeout(function() {
                    connected = false;
                    _connectionClosed();
                }, 0);
                return;
            }
            var error = message['error'];
            if (error)
                lastError = error;
            _sessionStatus(message);
            var wasConnected = connected;
            connected = (message['successful'] === true);
            if (!wasConnected && connected)
                _connectionOpened();
            else if (wasConnected && !connected)
                _connectionBroken();
        }
    
        function _connectionInitialized() {
            LOGGER.debug('Connection initialized');
            state = "initialized";
            eventManager.publish(eventManager.getEvents().CONNECTION_INITIALIZED);
        }
    
        function _connectionOpened() {
            LOGGER.debug('Connection opened');
            state = "opened";
            eventManager.publish(eventManager.getEvents().CONNECTION_OPENED);
        }
    
        function _connectionClosed() {
            LOGGER.debug('Connection closed');
            state = "closed";
            eventManager.publish(eventManager.getEvents().CONNECTION_CLOSED);
        }
    
        function _connectionBroken() {
            LOGGER.addErrorMessage('Connection broken');
            state = "broken";
            eventManager.publish(eventManager.getEvents().CONNECTION_BROKEN);
        }
    
        function _sessionStatus(message) {
            var ext = message['ext'];
            if (ext) {
                var sessionStatus = ext['glide.session.status'];
                loginWindowOverride = ext['glide.amb.login.window.override'] === true;
                LOGGER.debug('session.status - ' + sessionStatus);
                switch (sessionStatus) {
                    case 'session.logged.out':
                        if (loggedIn)
                            _logout();
                        break;
                    case 'session.logged.in':
                        if (!loggedIn)
                            _login();
                        break;
                    default:
                        LOGGER.debug("unknown session status - " + sessionStatus);
                        break;
                }
            }
        }
    
        function _login() {
            loggedIn = true;
            LOGGER.debug("LOGGED_IN event fire!");
            eventManager.publish(eventManager.getEvents().SESSION_LOGGED_IN);
            ambServerConnection.loginHide();
        }
    
        function _logout() {
            loggedIn = false;
            LOGGER.debug("LOGGED_OUT event fire!");
            eventManager.publish(eventManager.getEvents().SESSION_LOGGED_OUT);
            ambServerConnection.loginShow();
        }
        var modalContent = '<iframe src="/amb_login.do" frameborder="0" height="400px" width="405px" scrolling="no"></iframe>';
        var modalTemplate = '<div id="amb_disconnect_modal" tabindex="-1" aria-hidden="true" class="modal" role="dialog">' +
            '  <div class="modal-dialog small-modal" style="width:450px">' +
            '     <div class="modal-content">' +
            '        <header class="modal-header">' +
            '           <h4 id="small_modal1_title" class="modal-title">Login</h4>' +
            '        </header>' +
            '        <div class="modal-body">' +
            '        </div>' +
            '     </div>' +
            '  </div>' +
            '</div>';
    
        function _loginShow() {
            if (!loginWindowEnabled || loginWindowOverride)
                return;
            var dialog = new GlideModal('amb_disconnect_modal');
            if (dialog['renderWithContent']) {
                dialog.template = modalTemplate;
                dialog.renderWithContent(modalContent);
            } else {
                dialog.setBody(modalContent);
                dialog.render();
            }
            loginWindow = dialog;
        }
    
        function _loginHide() {
            if (!loginWindow)
                return;
            loginWindow.destroy();
            loginWindow = null;
        }
    
        function loginComplete() {
            _login();
        }
    
        function _getRelativePath(uri) {
            var relativePath = "";
            for (var i = 0; i < window.location.pathname.match(/\//g).length - 1; i++) {
                relativePath = "../" + relativePath;
            }
            return relativePath + uri;
        }
        ambServerConnection.loginShow = function() {
            _loginShow();
        };
        ambServerConnection.loginHide = function() {
            _loginHide();
        };
        ambServerConnection.getEvents = function() {
            return eventManager.getEvents();
        };
        ambServerConnection.getConnectionState = function() {
            return state;
        };
        ambServerConnection.getLastError = function() {
            return lastError;
        };
        ambServerConnection.setLastError = function(error) {
            lastError = error;
        };
        ambServerConnection.getErrorMessages = function() {
            return errorMessages;
        };
        ambServerConnection.isLoggedIn = function() {
            return loggedIn;
        };
        ambServerConnection.loginShow = function() {
            _loginShow();
        };
        ambServerConnection.loginHide = function() {
            _loginHide();
        };
        ambServerConnection.loginComplete = function() {
            _login();
        };
        ambServerConnection.getEvents = function() {
            return eventManager.getEvents();
        };
        ambServerConnection.subscribeToEvent = function(event, callback) {
            if (eventManager.getEvents().CONNECTION_OPENED == event && connected)
                callback();
            return eventManager.subscribe(event, callback);
        };
        ambServerConnection.unsubscribeFromEvent = function(id) {
            eventManager.unsubscribe(id);
        };
        ambServerConnection.getConnectionState = function() {
            return state;
        };
        ambServerConnection.isLoggedIn = function() {
            return loggedIn;
        };
        ambServerConnection.loginShow = function() {
            _loginShow();
        };
        ambServerConnection.loginHide = function() {
            _loginHide();
        };
        ambServerConnection.loginComplete = function() {
            _login();
        };
        ambServerConnection.isLoginWindowEnabled = function() {
            return loginWindowEnabled;
        };
        ambServerConnection.isLoginWindowOverride = function() {
            return loginWindowOverride;
        }
        return ambServerConnection;
    };;
    /*! RESOURCE: /scripts/amb.ChannelRedirect.js */
    amb.ChannelRedirect = function ChannelRedirect(cometd, serverConnection,
        channelProvider) {
        var initialized = false;
        var _cometd = cometd;
        var eventManager = new amb.EventManager({
            CHANNEL_REDIRECT: 'channel.redirect'
        });
        var LOGGER = new amb.Logger('amb.ChannelRedirect');
    
        function _onAdvice(advice) {
            LOGGER.debug('_onAdvice:' + advice.data.clientId);
            var fromChannel = channelProvider(advice.data.fromChannel);
            var toChannel = channelProvider(advice.data.toChannel);
            eventManager.publish(eventManager.getEvents().CHANNEL_REDIRECT, [fromChannel, toChannel]);
            LOGGER.debug(
                'published channel switch event, fromChannel:' + fromChannel.getName() +
                ', toChannel:' + toChannel.getName());
        }
        return {
            subscribeToEvent: function(event, callback) {
                return eventManager.subscribe(event, callback);
            },
            unsubscribeToEvent: function(id) {
                eventManager.unsubscribe(id);
            },
            getEvents: function() {
                return eventManager.getEvents();
            },
            initialize: function() {
                if (!initialized) {
                    var channelName = '/sn/meta/channel_redirect/' + _cometd.getClientId();
                    var metaChannel = channelProvider(channelName);
                    metaChannel.newListener(serverConnection, null).subscribe(_onAdvice);
                    LOGGER.debug("ChannelRedirect initialized: " + channelName);
                    initialized = true;
                }
            }
        }
    };;
    /*! RESOURCE: /scripts/amb.ChannelListener.js */
    amb.ChannelListener = function ChannelListener(channel, serverConnection,
        channelRedirect) {
        var id;
        var subscriberCallback;
        var LOGGER = new amb.Logger('amb.ChannelListener');
        var channelRedirectId = null;
        var connectOpenedEventId;
        var currentChannel = channel;
        return {
            getCallback: function() {
                return subscriberCallback;
            },
            getID: function() {
                return id;
            },
            subscribe: function(callback) {
                subscriberCallback = callback;
                if (channelRedirect)
                    channelRedirectId = channelRedirect.subscribeToEvent(
                        channelRedirect.getEvents().CHANNEL_REDIRECT, this._switchToChannel.bind(this));
                connectOpenedEventId = serverConnection.subscribeToEvent(serverConnection.getEvents().CONNECTION_OPENED,
                    this._subscribeWhenReady.bind(this));
                LOGGER.debug("Subscribed from channel: " + currentChannel.getName());
                return this;
            },
            resubscribe: function() {
                return this.subscribe(subscriberCallback);
            },
            _switchToChannel: function(fromChannel, toChannel) {
                if (!fromChannel || !toChannel)
                    return;
                if (fromChannel.getName() != currentChannel.getName())
                    return;
                this.unsubscribe();
                currentChannel = toChannel;
                this.subscribe(subscriberCallback);
            },
            _subscribeWhenReady: function() {
                LOGGER.debug("Subscribing to '" + currentChannel.getName() + "'...");
                id = currentChannel.subscribe(this);
            },
            unsubscribe: function() {
                channelRedirect.unsubscribeToEvent(channelRedirectId);
                currentChannel.unsubscribe(this);
                serverConnection.unsubscribeFromEvent(connectOpenedEventId);
                LOGGER.debug("Unsubscribed from channel: " + currentChannel.getName());
                return this;
            },
            publish: function(message) {
                currentChannel.publish(message);
            },
            getName: function() {
                return currentChannel.getName();
            }
        }
    };;
    /*! RESOURCE: /scripts/amb.Channel.js */
    amb.Channel = function Channel(cometd, channelName, initialized) {
        var subscription = null;
        var listeners = [];
        var LOGGER = new amb.Logger('amb.Channel');
        var idCounter = 0;
        var _initialized = initialized;
    
        function _disconnected() {
            var status = cometd.getStatus();
            return status === 'disconnecting' || status === 'disconnected';
        }
        return {
            newListener: function(serverConnection,
                channelRedirect) {
                return new amb.ChannelListener(this, serverConnection, channelRedirect);
            },
            subscribe: function(listener) {
                if (!listener.getCallback()) {
                    LOGGER.addErrorMessage('Cannot subscribe to channel: ' + channelName +
                        ', callback not provided');
                    return;
                }
                if (!subscription && _initialized) {
                    subscription = cometd.subscribe(channelName, this._handleResponse.bind(this));
                    LOGGER.debug('Successfully subscribed to channel: ' + channelName);
                }
                for (var i = 0; i < listeners.length; i++) {
                    if (listeners[i] === listener) {
                        LOGGER.debug('Channel listener already in the list');
                        return listener.getID();
                    }
                }
                var id = idCounter++;
                listeners.push(listener);
                return id;
            },
            subscribeOnInitCompletion: function(redirect) {
                _initialized = true;
                subscription = null;
                for (var i = 0; i < listeners.length; i++) {
                    listeners[i].subscribe();
                    LOGGER.debug('Successfully subscribed to channel: ' + channelName);
                }
            },
            resubscribe: function() {
                subscription = null;
                for (var i = 0; i < listeners.length; i++)
                    listeners[i].resubscribe();
            },
            _handleResponse: function(message) {
                for (var i = 0; i < listeners.length; i++)
                    listeners[i].getCallback()(message);
            },
            unsubscribe: function(listener) {
                if (!listener) {
                    LOGGER.addErrorMessage('Cannot unsubscribe from channel: ' + channelName +
                        ', listener argument does not exist');
                    return;
                }
                for (var i = 0; i < listeners.length; i++) {
                    if (listeners[i].getID() == listener.getID())
                        listeners.splice(i, 1);
                }
                if (listeners.length < 1 && subscription && !_disconnected()) {
                    cometd.unsubscribe(subscription);
                    subscription = null;
                }
                LOGGER.debug('Successfully unsubscribed from channel: ' + channelName);
            },
            publish: function(message) {
                cometd.publish(channelName, message);
            },
            getName: function() {
                return channelName;
            }
        }
    };;
    /*! RESOURCE: /scripts/amb.MessageClient.js */
    (function($) {
        amb.MessageClient = function MessageClient() {
            var cometd = new $.Cometd();
            cometd.unregisterTransport('websocket');
            cometd.unregisterTransport('callback-polling');
            var serverConnection = new amb.ServerConnection(cometd);
            var channels = {};
            var LOGGER = new amb.Logger('amb.MessageClient');
            var channelRedirect = null;
            var connected = false;
            var initialized = false;
            var uninitializedChannels = [];
            serverConnection.subscribeToEvent(serverConnection.getEvents().CONNECTION_BROKEN, _connectionBroken);
            serverConnection.subscribeToEvent(serverConnection.getEvents().CONNECTION_OPENED, _connectionOpened);
            serverConnection.subscribeToEvent(serverConnection.getEvents().CONNECTION_INITIALIZED, _connectionInitialized);
            var _connectionBrokenEvent = false;
    
            function _connectionBroken() {
                LOGGER.debug("connection broken!");
                _connectionBrokenEvent = true;
            }
    
            function _connectionInitialized() {
                initialized = true;
                _initChannelRedirect();
                channelRedirect.initialize();
                LOGGER.debug("Connection initialized. Initializing " + uninitializedChannels.length + " channels.");
                for (var i = 0; i < uninitializedChannels.length; i++) {
                    uninitializedChannels[i].subscribeOnInitCompletion();
                }
                uninitializedChannels = [];
            }
    
            function _connectionOpened() {
                if (_connectionBrokenEvent) {
                    LOGGER.debug("connection opened!");
                    _connectionBrokenEvent = false;
                    var sc = serverConnection;
                    if (sc.getLastError() !== sc.getErrorMessages().UNKNOWN_CLIENT)
                        return;
                    sc.setLastError(null);
                    LOGGER.debug("channel resubscribe!");
                    $.ajax({
                        url: "/amb_session_setup.do",
                        method: "GET",
                        contentType: "application/json;charset=UTF-8",
                        data: "",
                        dataType: "HTML",
                        headers: {
                            'X-UserToken': window.g_ck
                        }
                    }).done(function() {
                        for (var name in channels) {
                            var channel = channels[name];
                            channel.resubscribe();
                        }
                    });
                }
            }
    
            function _initChannelRedirect() {
                if (channelRedirect)
                    return;
                channelRedirect = new amb.ChannelRedirect(cometd, serverConnection, _getChannel);
            }
    
            function _getChannel(channelName) {
                if (channelName in channels)
                    return channels[channelName];
                var channel = new amb.Channel(cometd, channelName, initialized);
                channels[channelName] = channel;
                if (!initialized)
                    uninitializedChannels.push(channel);
                return channel;
            }
            return {
                getServerConnection: function() {
                    return serverConnection;
                },
                isLoggedIn: function() {
                    return serverConnection.isLoggedIn();
                },
                loginComplete: function() {
                    serverConnection.loginComplete();
                },
                connect: function() {
                    if (connected) {
                        LOGGER.addInfoMessage(">>> connection exists, request satisfied");
                        return;
                    }
                    connected = true;
                    serverConnection.connect();
                },
                reload: function() {
                    connected = false;
                    serverConnection.reload();
                },
                abort: function() {
                    connected = false;
                    serverConnection.abort();
                },
                disconnect: function() {
                    connected = false;
                    serverConnection.disconnect();
                },
                getConnectionEvents: function() {
                    return serverConnection.getEvents();
                },
                subscribeToEvent: function(event, callback) {
                    return serverConnection.subscribeToEvent(event, callback);
                },
                unsubscribeFromEvent: function(id) {
                    serverConnection.unsubscribeFromEvent(id);
                },
                getConnectionState: function() {
                    return serverConnection.getConnectionState();
                },
                getClientId: function() {
                    return cometd.getClientId();
                },
                getChannel: function(channelName) {
                    _initChannelRedirect();
                    var channel = _getChannel(channelName);
                    return channel.newListener(serverConnection, channelRedirect);
                },
                registerExtension: function(extensionName, extension) {
                    cometd.registerExtension(extensionName, extension);
                },
                unregisterExtension: function(extensionName) {
                    cometd.unregisterExtension(extensionName);
                },
                batch: function(block) {
                    cometd.batch(block);
                }
            }
        };
    })(jQuery1110);;
    /*! RESOURCE: /scripts/amb.MessageClientBuilder.js */
    (function($) {
        amb.getClient = function() {
            return getClient();
        }
    
        function getClient() {
            var _window = window.self;
            try {
                if (!(window.MSInputMethodContext && document.documentMode)) {
                    while (_window != _window.parent) {
                        if (_window.g_ambClient)
                            break;
                        _window = _window.parent;
                    }
                }
                if (_window.g_ambClient)
                    return _window.g_ambClient;
            } catch (e) {
                console.log("AMB getClient() tried to access parent from an iFrame. Caught error: " + e);
            }
            var client = buildClient();
            setClient(client);
            return client;
        }
    
        function setClient(client) {
            var _window = window.self;
            _window.g_ambClient = client;
            $(_window).unload(function() {
                _window.g_ambClient.disconnect();
            });
            _window.g_ambClient.connect();
        }
    
        function buildClient() {
            return (function() {
                var ambClient = new amb.MessageClient();
                return {
                    getServerConnection: function() {
                        return ambClient.getServerConnection();
                    },
                    connect: function() {
                        ambClient.connect();
                    },
                    abort: function() {
                        ambClient.abort();
                    },
                    disconnect: function() {
                        ambClient.disconnect();
                    },
                    getConnectionState: function() {
                        return ambClient.getConnectionState();
                    },
                    getState: function() {
                        return ambClient.getConnectionState();
                    },
                    getClientId: function() {
                        return ambClient.getClientId();
                    },
                    getChannel: function(channelName) {
                        var channel = ambClient.getChannel(channelName);
                        var originalSubscribe = channel.subscribe;
                        var originalUnsubscribe = channel.unsubscribe;
                        channel.subscribe = function(listener) {
                            originalSubscribe.call(channel, listener);
                            $(window).unload(function(event) {
                                originalUnsubscribe.call(channel);
                            });
                            return channel;
                        };
                        return channel;
                    },
                    getChannel0: function(channelName) {
                        return ambClient.getChannel(channelName);
                    },
                    registerExtension: function(extensionName, extension) {
                        ambClient.registerExtension(extensionName, extension);
                    },
                    unregisterExtension: function(extensionName) {
                        ambClient.unregisterExtension(extensionName);
                    },
                    batch: function(block) {
                        ambClient.batch(block);
                    },
                    subscribeToEvent: function(event, callback) {
                        return ambClient.subscribeToEvent(event, callback);
                    },
                    unsubscribeFromEvent: function(id) {
                        ambClient.unsubscribeFromEvent(id);
                    },
                    isLoggedIn: function() {
                        return ambClient.isLoggedIn();
                    },
                    getConnectionEvents: function() {
                        return ambClient.getConnectionEvents();
                    },
                    getEvents: function() {
                        return ambClient.getConnectionEvents();
                    },
                    loginComplete: function() {
                        ambClient.loginComplete();
                    }
                };
            })();
        }
    })(jQuery1110);;
    /*! RESOURCE: /scripts/amb_initialize.js */
    if (typeof g_amb_on_login === 'undefined') {
        amb.getClient();
    };;
    /*! RESOURCE: /scripts/app.ng.amb/app.ng.amb.js */
    angular.module("ng.amb", ['sn.common.presence', 'sn.common.util'])
        .value("ambLogLevel", 'info')
        .value("ambServletURI", '/amb')
        .value("cometd", angular.element.cometd)
        .value("ambLoginWindow", 'true');;
    /*! RESOURCE: /scripts/app.ng.amb/service.AMB.js */
    angular.module("ng.amb").service("amb", function(AMBOverlay, $window, $q, $log, $rootScope, $timeout) {
        "use strict";
        var ambClient = null;
        var _window = $window.self;
        var loginWindow = null;
        var sameScope = false;
        if (_window.g_ambClient) {
            ambClient = _window.g_ambClient;
            sameScope = true;
        }
        if (!ambClient)
            ambClient = amb.getClient();
        if (sameScope) {
            var serverConnection = ambClient.getServerConnection();
            serverConnection.loginShow = function() {
                if (!serverConnection.isLoginWindowEnabled())
                    return;
                if (loginWindow && loginWindow.isVisible())
                    return;
                if (serverConnection.isLoginWindowOverride())
                    return;
                loginWindow = new AMBOverlay();
                loginWindow.render();
                loginWindow.show();
            };
            serverConnection.loginHide = function() {
                if (!loginWindow)
                    return;
                loginWindow.hide();
                loginWindow.destroy();
                loginWindow = null;
            }
        }
        var connected = $q.defer();
        var connectionInterrupted = false;
        var monitorAMB = false;
        $timeout(function() {
            monitorAMB = true;
        }, 5 * 1000);
    
        function ambInterrupted() {
            var state = ambClient.getState();
            return monitorAMB && state !== "opened" && state !== "initialized"
        }
        var interruptionTimeout;
        var extendedInterruption = false;
    
        function setInterrupted(eventName) {
            connectionInterrupted = true;
            $rootScope.$broadcast(eventName);
            if (!interruptionTimeout) {
                interruptionTimeout = $timeout(function() {
                    extendedInterruption = true;
                }, 30 * 1000)
            }
            connected = $q.defer();
        }
        var connectOpenedEventId = ambClient.subscribeToEvent("connection.opened", function() {
            $rootScope.$broadcast("amb.connection.opened");
            if (interruptionTimeout) {
                $timeout.cancel(interruptionTimeout);
                interruptionTimeout = null;
            }
            extendedInterruption = false;
            if (connectionInterrupted) {
                connectionInterrupted = false;
                $rootScope.$broadcast("amb.connection.recovered");
            }
            connected.resolve();
        });
        var connectClosedEventId = ambClient.subscribeToEvent("connection.closed", function() {
            setInterrupted("amb.connection.closed");
        });
        var connectBrokenEventId = ambClient.subscribeToEvent("connection.broken", function() {
            setInterrupted("amb.connection.broken");
        });
        jQuery(window).unload(function fixMemoryLeakInGlobalAMBEventManager(event) {
            ambClient.unsubscribeFromEvent(connectOpenedEventId);
            ambClient.unsubscribeFromEvent(connectClosedEventId);
            ambClient.unsubscribeFromEvent(connectBrokenEventId);
            jQuery(this).unbind(event);
        });
        ambClient.connect();
        return {
            getServerConnection: function() {
                return ambClient.getServerConnection();
            },
            connect: function() {
                ambClient.connect();
                return connected.promise;
            },
            get interrupted() {
                return ambInterrupted();
            },
            get extendedInterruption() {
                return extendedInterruption;
            },
            get connected() {
                return connected.promise;
            },
            abort: function() {
                ambClient.abort();
            },
            disconnect: function() {
                ambClient.disconnect();
            },
            getConnectionState: function() {
                return ambClient.getConnectionState();
            },
            getClientId: function() {
                return ambClient.getClientId();
            },
            getChannel: function(channelName) {
                var channel = ambClient.getChannel0(channelName);
                var originalSubscribe = channel.subscribe;
                var originalUnsubscribe = channel.unsubscribe;
                channel.subscribe = function(listener) {
                    originalSubscribe.call(channel, listener);
                    jQuery(window).unload(function() {
                        originalUnsubscribe.call(channel);
                    });
                    return channel;
                };
                return channel;
            },
            registerExtension: function(extensionName, extension) {
                ambClient.registerExtension(extensionName, extension);
            },
            unregisterExtension: function(extensionName) {
                ambClient.unregisterExtension(extensionName);
            },
            batch: function(batch) {
                ambClient.batch(batch);
            },
            getState: function() {
                return ambClient.getState();
            },
            getFilterString: function(filter) {
                filter = filter.
                replace(/\^EQ/g, '').
                replace(/\^ORDERBY(?:DESC)?[^^]*/g, '').
                replace(/^GOTO/, '');
                return btoa(filter).replace(/=/g, '-');
            },
            getChannelRW: function(table, filter) {
                var t = '/rw/default/' + table + '/' + this.getFilterString(filter);
                return this.getChannel(t);
            },
            isLoggedIn: function() {
                return ambClient.isLoggedIn();
            },
            subscribeToEvent: function(event, callback) {
                ambClient.subscribeToEvent(event, callback);
            },
            getConnectionEvents: function() {
                return ambClient.getConnectionEvents();
            },
            getEvents: function() {
                return ambClient.getConnectionEvents();
            },
            loginComplete: function() {
                ambClient.loginComplete();
            }
        };
    });;
    /*! RESOURCE: /scripts/app.ng.amb/controller.AMBRecordWatcher.js */
    angular.module("ng.amb").controller("AMBRecordWatcher", function($scope, $timeout, $window) {
        "use strict";
        var amb = $window.top.g_ambClient;
        $scope.messages = [];
        var lastFilter;
        var watcherChannel;
        var watcher;
    
        function onMessage(message) {
            $scope.messages.push(message.data);
        }
        $scope.getState = function() {
            return amb.getState();
        };
        $scope.initWatcher = function() {
            angular.element(":focus").blur();
            if (!$scope.filter || $scope.filter === lastFilter)
                return;
            lastFilter = $scope.filter;
            console.log("initiating watcher on " + $scope.filter);
            $scope.messages = [];
            if (watcher) {
                watcher.unsubscribe();
            }
            var base64EncodeQuery = btoa($scope.filter).replace(/=/g, '-');
            var channelId = '/rw/' + base64EncodeQuery;
            watcherChannel = amb.getChannel(channelId)
            watcher = watcherChannel.subscribe(onMessage);
        };
        amb.connect();
    });
    /*! RESOURCE: /scripts/app.ng.amb/factory.snRecordWatcher.js */
    angular.module("ng.amb").factory('snRecordWatcher', function($rootScope, amb, $timeout, snPresence, $log, urlTools) {
        "use strict";
        var watcherChannel;
        var connected = false;
        var diagnosticLog = true;
    
        function initWatcher(table, sys_id, query) {
            if (!table)
                return;
            if (sys_id)
                var filter = "sys_id=" + sys_id;
            else
                filter = query;
            if (!filter)
                return;
            return initChannel(table, filter);
        }
    
        function initList(table, query) {
            if (!table)
                return;
            query = query || "sys_idISNOTEMPTY";
            return initChannel(table, query);
        }
    
        function initTaskList(list, prevChannel) {
            if (prevChannel)
                prevChannel.unsubscribe();
            var sys_ids = list.toString();
            var filter = "sys_idIN" + sys_ids;
            return initChannel("task", filter);
        }
    
        function initChannel(table, filter) {
            if (isBlockedTable(table)) {
                $log.log("Blocked from watching", table);
                return null;
            }
            if (diagnosticLog)
                log(">>> init " + table + "?" + filter);
            watcherChannel = amb.getChannelRW(table, filter);
            watcherChannel.subscribe(onMessage);
            amb.connect();
            return watcherChannel;
        }
    
        function onMessage(message) {
            var r = message.data;
            var c = message.channel;
            if (diagnosticLog)
                log(">>> record " + r.operation + ": " + r.table_name + "." + r.sys_id + " " + r.display_value);
            $rootScope.$broadcast('record.updated', r);
            $rootScope.$broadcast("sn.stream.tap");
            $rootScope.$broadcast('list.updated', r, c);
        }
    
        function log(message) {
            $log.log(message);
        }
    
        function isBlockedTable(table) {
            return table == 'sys_amb_message' || table.startsWith('sys_rw');
        }
        return {
            initTaskList: initTaskList,
            initChannel: initChannel,
            init: function() {
                var location = urlTools.parseQueryString(window.location.search);
                var table = location['table'] || location['sysparm_table'];
                var sys_id = location['sys_id'] || location['sysparm_sys_id'];
                var query = location['sysparm_query'];
                initWatcher(table, sys_id, query);
                snPresence.init(table, sys_id, query);
            },
            initList: initList,
            initRecord: function(table, sysId) {
                initWatcher(table, sysId, null);
                snPresence.initWithDocument(table, sysId);
            }
        }
    });;
    /*! RESOURCE: /scripts/app.ng.amb/factory.AMBOverlay.js */
    angular.module("ng.amb").factory("AMBOverlay", function($templateCache, $compile, $rootScope) {
        "use strict";
        var showCallbacks = [],
            hideCallbacks = [],
            isRendered = false,
            modal,
            modalScope,
            modalOptions;
        var defaults = {
            backdrop: 'static',
            keyboard: false,
            show: true
        };
    
        function AMBOverlay(config) {
            config = config || {};
            if (angular.isFunction(config.onShow))
                showCallbacks.push(config.onShow);
            if (angular.isFunction(config.onHide))
                hideCallbacks.push(config.onHide);
    
            function lazyRender() {
                if (!angular.element('html')['modal']) {
                    var bootstrapInclude = "/scripts/bootstrap3/bootstrap.js";
                    ScriptLoader.getScripts([bootstrapInclude], renderModal);
                } else
                    renderModal();
            }
    
            function renderModal() {
                if (isRendered)
                    return;
                modalScope = angular.extend($rootScope.$new(), config);
                modal = $compile($templateCache.get("amb_disconnect_modal.xml"))(modalScope);
                angular.element("body").append(modal);
                modal.on("shown.bs.modal", function(e) {
                    for (var i = 0, len = showCallbacks.length; i < len; i++)
                        showCallbacks[i](e);
                });
                modal.on("hidden.bs.modal", function(e) {
                    for (var i = 0, len = hideCallbacks.length; i < len; i++)
                        hideCallbacks[i](e);
                });
                modalOptions = angular.extend({}, defaults, config);
                modal.modal(modalOptions);
                isRendered = true;
            }
    
            function showModal() {
                if (isRendered)
                    modal.modal('show');
            }
    
            function hideModal() {
                if (isRendered)
                    modal.modal('hide');
            }
    
            function destroyModal() {
                if (!isRendered)
                    return;
                modal.modal('hide');
                modal.remove();
                modalScope.$destroy();
                modalScope = void(0);
                isRendered = false;
                var pos = showCallbacks.indexOf(config.onShow);
                if (pos >= 0)
                    showCallbacks.splice(pos, 1);
                pos = hideCallbacks.indexOf(config.onShow);
                if (pos >= 0)
                    hideCallbacks.splice(pos, 1);
            }
            return {
                render: lazyRender,
                destroy: destroyModal,
                show: showModal,
                hide: hideModal,
                isVisible: function() {
                    if (!isRendered)
                        false;
                    return modal.visible();
                }
            }
        }
        $templateCache.put('amb_disconnect_modal.xml',
            '<div id="amb_disconnect_modal" tabindex="-1" aria-hidden="true" class="modal" role="dialog">' +
            '	<div class="modal-dialog small-modal" style="width:450px">' +
            '		<div class="modal-content">' +
            '			<header class="modal-header">' +
            '				<h4 id="small_modal1_title" class="modal-title">{{title || "Login"}}</h4>' +
            '			</header>' +
            '			<div class="modal-body">' +
            '			<iframe class="concourse_modal" ng-src=\'{{iframe || "/amb_login.do"}}\' frameborder="0" scrolling="no" height="400px" width="405px"></iframe>' +
            '			</div>' +
            '		</div>' +
            '	</div>' +
            '</div>'
        );
        return AMBOverlay;
    });;;
    /*! RESOURCE: /scripts/sn/common/presence/_module.js */
    angular.module('sn.common.presence', ['ng.amb', 'sn.common.glide']).config(function($provide) {
        "use strict";
        $provide.constant("PRESENCE_DISABLED", "false" === "true");
    });;
    /*! RESOURCE: /scripts/sn/common/presence/factory.snPresence.js */
    angular.module("sn.common.presence").factory('snPresence', function($rootScope, $window, $log, amb, $timeout, $http, snRecordPresence, snTabActivity, urlTools, PRESENCE_DISABLED) {
        "use strict";
        var REST = {
            PRESENCE: "/api/now/ui/presence"
        };
        var databaseInterval = ($window.NOW.presence_interval || 15) * 1000;
        var initialized = false;
        var primary = false;
        var presenceArray = [];
        var serverTimeMillis;
        var skew = 0;
        var st = 0;
    
        function init() {
            var location = urlTools.parseQueryString(window.location.search);
            var table = location['table'] || location['sysparm_table'];
            var sys_id = location['sys_id'] || location['sysparm_sys_id'];
            var query = location['sysparm_query'];
            initPresence(table, sys_id, query);
        }
    
        function initPresence(t, id) {
            if (PRESENCE_DISABLED)
                return;
            if (!initialized) {
                initialized = true;
                initRootScopes();
                if (!primary) {
                    CustomEvent.observe('sn.presence', onPresenceEvent);
                    CustomEvent.fireTop('sn.presence.ping');
                } else {
                    presenceArray = getLocalPresence();
                    if (presenceArray)
                        $timeout(schedulePresence, 100);
                    else
                        updateDatabase();
                }
            }
            snRecordPresence.initPresence(t, id);
        }
    
        function onPresenceEvent(parms) {
            presenceArray = parms;
            $timeout(broadcastPresence);
        }
    
        function initRootScopes() {
            if ($window.NOW.presence_scopes) {
                var ps = $window.NOW.presence_scopes;
                if (ps.indexOf($rootScope) == -1)
                    ps.push($rootScope);
            } else {
                $window.NOW.presence_scopes = [$rootScope];
                primary = CustomEvent.isTopWindow();
            }
        }
    
        function updateDatabase() {
            presenceArray = getLocalPresence();
            if (presenceArray) {
                determineStatus();
                $timeout(schedulePresence);
                return;
            }
            if (!amb.isLoggedIn() || !snTabActivity.isPrimary) {
                $timeout(schedulePresence);
                return;
            }
            var p = {
                user_agent: navigator.userAgent,
                ua_time: new Date().toISOString(),
                href: window.location.href,
                pathname: window.location.pathname,
                search: window.location.search,
                path: window.location.pathname + window.location.search
            };
            st = new Date().getTime();
            $http.post(REST.PRESENCE + '?sysparm_auto_request=true&cd=' + st, p).success(function(data) {
                var rt = new Date().getTime() - st;
                if (rt > 500)
                    console.log("snPresence response time " + rt + "ms");
                if (data.result && data.result.presenceArray) {
                    presenceArray = data.result.presenceArray;
                    setLocalPresence(presenceArray);
                    serverTimeMillis = data.result.serverTimeMillis;
                    skew = new Date().getTime() - serverTimeMillis;
                    var t = Math.floor(skew / 1000);
                    if (t < -15)
                        console.log(">>>>> server ahead " + Math.abs(t) + " seconds");
                    else if (t > 15)
                        console.log(">>>>> browser time ahead " + t + " seconds");
                }
                schedulePresence();
            }).error(function(response, status) {
                console.log("snPresence " + status);
                if (429 == status)
                    $timeout(updateDatabase, databaseInterval);
                else
                    schedulePresence();
            })
        }
    
        function schedulePresence() {
            $timeout(updateDatabase, databaseInterval);
            determineStatus();
            broadcastPresence();
        }
    
        function broadcastPresence() {
            $rootScope.$broadcast("sn.presence", presenceArray);
            if (!primary)
                return;
            CustomEvent.fireAll('sn.presence', presenceArray);
        }
    
        function determineStatus() {
            if (!presenceArray || !presenceArray.forEach) {
                $log.log("factory.snPresence >>> server error @ " + new Date());
                return;
            }
            var t = new Date().getTime();
            t -= skew;
            presenceArray.forEach(function(p) {
                var x = 0 + p.last_on;
                var y = t - x;
                p.status = "online";
                if (y > (5 * databaseInterval))
                    p.status = "offline";
                else if (y > (3 * databaseInterval))
                    p.status = "probably offline";
                else if (y > (2.5 * databaseInterval))
                    p.status = "maybe offline";
            })
        }
    
        function setLocalPresence(value) {
            var p = {
                saved: new Date().getTime(),
                presenceArray: value
            }
            $window.localStorage.setItem('snPresence', angular.toJson(p));
        }
    
        function getLocalPresence() {
            var p = $window.localStorage.getItem('snPresence');
            if (!p)
                return null;
            try {
                p = angular.fromJson(p);
            } catch (e) {
                p = {};
            }
            if (!p.presenceArray)
                return null;
            var now = new Date().getTime();
            if (now - p.saved >= databaseInterval)
                return null;
            return p.presenceArray;
        }
        return {
            init: init,
            initWithDocument: initPresence,
            initPresence: initPresence
        }
    });;
    /*! RESOURCE: /scripts/sn/common/presence/factory.snRecordPresence.js */
    angular.module("sn.common.presence").factory('snRecordPresence', function($rootScope, $location, amb, $timeout, $window, PRESENCE_DISABLED, snTabActivity) {
        "use strict";
        var statChannel;
        var interval = 20 * 1000;
        var sessions = {};
        var timer;
        var primary = false;
        var table;
        var sys_id;
    
        function initPresence(t, id) {
            if (PRESENCE_DISABLED)
                return;
            if (!t || !id)
                return;
            if (t == table && id == sys_id)
                return;
            initRootScopes();
            if (!primary)
                return;
            termPresence();
            table = t;
            sys_id = id;
            var recordPresence = "/sn/rp/" + table + "/" + sys_id;
            $rootScope.me = NOW.session_id;
            statChannel = amb.getChannel(recordPresence);
            statChannel.subscribe(onStatus);
            amb.connected.then(function() {
                setStatus("entered");
                $rootScope.status = "viewing";
            });
            timer = $timeout(managePresence, interval);
            return statChannel;
        }
    
        function initRootScopes() {
            if ($window.NOW.record_presence_scopes) {
                var ps = $window.NOW.record_presence_scopes;
                if (ps.indexOf($rootScope) == -1) {
                    ps.push($rootScope);
                    CustomEvent.observe('sn.sessions', onPresenceEvent);
                }
            } else {
                $window.NOW.record_presence_scopes = [$rootScope];
                primary = true;
            }
        }
    
        function onPresenceEvent(sessionsToSend) {
            $rootScope.$broadcast("sn.sessions", sessionsToSend);
            $rootScope.$broadcast("sp.sessions", sessionsToSend);
        }
    
        function termPresence() {
            if (timer)
                $timeout.cancel(timer);
            if (!statChannel)
                return;
            publish("exited");
            statChannel.unsubscribe();
            statChannel = table = sys_id = null;
        }
    
        function setStatus(status) {
            if (status == $rootScope.status)
                return;
            $rootScope.status = status;
            publish($rootScope.status);
        }
    
        function publish(status) {
            if (!statChannel)
                return;
            if (amb.getState() !== "opened")
                return;
            statChannel.publish({
                status: status,
                session_id: NOW.session_id,
                user_name: NOW.user_name,
                user_id: NOW.user_id,
                user_display_name: NOW.user_display_name,
                user_initials: NOW.user_initials,
                user_avatar: NOW.user_avatar,
                ua: navigator.userAgent,
                table: table,
                sys_id: sys_id,
                time: new Date().toString().substring(0, 24)
            });
        }
    
        function onStatus(message) {
            var d = message.data;
            if (d.session_id == NOW.session_id)
                return;
            var s = sessions[d.session_id];
            if (s)
                angular.extend(s, d);
            else
                s = sessions[d.session_id] = d;
            s.lastUpdated = new Date();
            broadcastSessions();
            if (s.status == 'entered')
                publish($rootScope.status);
        }
    
        function managePresence() {
            var now = new Date().getTime();
            var deleted = false;
            Object.keys(sessions).forEach(function(id) {
                var s = sessions[id];
                if (!s.lastUpdated)
                    return;
                var last = s.lastUpdated.getTime();
                var t = now - last;
                s.lastSeen = t / 1000;
                if (s.status === 'exited') {
                    deleted = true;
                    delete sessions[id];
                }
                if (t > interval * 2)
                    s.status = 'probably left';
                if (t > interval * 4) {
                    deleted = true;
                    delete sessions[id];
                }
            });
            if (Object.keys(sessions).length !== 0)
                publish($rootScope.status);
            timer = $timeout(managePresence, interval);
            if (deleted)
                broadcastSessions();
        }
    
        function broadcastSessions() {
            var sessionsToSend = getUniqueSessions();
            $rootScope.$broadcast("sn.sessions", sessionsToSend);
            $rootScope.$broadcast("sp.sessions", sessionsToSend);
            if (primary)
                $timeout(function() {
                    CustomEvent.fire('sn.sessions', sessionsToSend);
                })
        }
    
        function getUniqueSessions() {
            var uniqueSessionsByUser = {};
            var sessionKeys = Object.keys(sessions);
            sessionKeys.forEach(function(key) {
                var session = sessions[key];
                if (session.user_id == NOW.user_id)
                    return;
                if (session.user_id in uniqueSessionsByUser) {
                    var otherSession = uniqueSessionsByUser[session.user_id];
                    var thisPrecedence = getStatusPrecedence(session.status);
                    var otherPrecedence = getStatusPrecedence(otherSession.status);
                    uniqueSessionsByUser[session.user_id] = thisPrecedence < otherPrecedence ? session : otherSession;
                    return
                }
                uniqueSessionsByUser[session.user_id] = session;
            });
            var uniqueSessions = {};
            angular.forEach(uniqueSessionsByUser, function(item) {
                uniqueSessions[item.session_id] = item;
            });
            return uniqueSessions;
        }
    
        function getStatusPrecedence(status) {
            switch (status) {
                case 'typing':
                    return 0;
                case 'viewing':
                    return 1;
                case 'entered':
                    return 2;
                case 'exited':
                case 'probably left':
                    return 4;
                case 'offline':
                    return 5;
                default:
                    return 3;
            }
        }
        $rootScope.$on("record.typing", function(evt, data) {
            setStatus(data.status);
        });
        var idleTable, idleSysID;
        snTabActivity.onIdle({
            onIdle: function RecordPresenceTabIdle() {
                idleTable = table;
                idleSysID = sys_id;
                sessions = {};
                termPresence();
                broadcastSessions();
            },
            onReturn: function RecordPresenceTabActive() {
                initPresence(idleTable, idleSysID, true);
                idleTable = idleSysID = void(0);
            },
            delay: interval * 4
        });
        return {
            initPresence: initPresence,
            termPresence: termPresence
        }
    });;
    /*! RESOURCE: /scripts/sn/common/presence/directive.snPresence.js */
    angular.module('sn.common.presence').directive('snPresence', function(snPresence, $rootScope, $timeout) {
        'use strict';
        $timeout(snPresence.init, 100);
        var presences = {};
        $rootScope.$on('sn.presence', function(event, presenceArray) {
            if (!presenceArray) {
                angular.forEach(presences, function(p) {
                    p.status = "offline";
                });
                return;
            }
            presenceArray.forEach(function(presence) {
                presences[presence.user] = presence;
            });
        });
        return {
            restrict: 'EA',
            replace: false,
            scope: {
                snPresence: '=',
                user: '='
            },
            link: function(scope, element) {
                if (!element.hasClass('presence'))
                    element.addClass('presence');
    
                function updatePresence() {
                    var id = scope.snPresence || scope.user;
                    if (presences[id]) {
                        var status = presences[id].status;
                        if (status === 'maybe offline' || status === 'probably offline') {
                            element.removeClass('presence-online presence-offline presence-away');
                            element.addClass('presence-away');
                        } else if (status == "offline" && !element.hasClass('presence-offline')) {
                            element.removeClass('presence-online presence-away');
                            element.addClass('presence-offline');
                        } else if ((status == "online" || status == "entered" || status == "viewing") && !element.hasClass('presence-online')) {
                            element.removeClass('presence-offline presence-away');
                            element.addClass('presence-online');
                        }
                    } else {
                        if (!element.hasClass('presence-offline'))
                            element.addClass('presence-offline');
                    }
                }
                $rootScope.$on('sn.presence', updatePresence);
                updatePresence();
            }
        };
    });;;
    /*! RESOURCE: /scripts/sn/common/user_profile/js_includes_user_profile.js */
    /*! RESOURCE: /scripts/sn/common/user_profile/_module.js */
    angular.module("sn.common.user_profile", []);;
    /*! RESOURCE: /scripts/sn/common/user_profile/directive.snUserProfile.js */
    angular.module('sn.common.user_profile').directive('snUserProfile', function(getTemplateUrl, snCustomEvent, $window, avatarProfilePersister) {
        "use strict";
        return {
            replace: true,
            restrict: 'E',
            templateUrl: getTemplateUrl('snUserProfile.xml'),
            scope: {
                profile: "=",
                showDirectMessagePrompt: "="
            },
            link: function(scope) {
                scope.showDirectMessagePromptFn = function() {
                    if (scope.showDirectMessagePrompt) {
                        var activeUserID = $window.NOW.user_id || "";
                        return !(!scope.profile ||
                            activeUserID === scope.profile.sysID ||
                            (scope.profile.document && activeUserID === scope.profile.document));
                    } else {
                        return false;
                    }
                };
            },
            controller: function($scope, snConnectService) {
                if ($scope.profile && $scope.profile.userID && avatarProfilePersister.getAvatar($scope.profile.userID))
                    $scope.profile = avatarProfilePersister.getAvatar($scope.profile.userID);
                $scope.$emit("sn-user-profile.ready");
                $scope.openDirectMessageConversation = function(evt) {
                    if (evt.keyCode === 9)
                        return;
                    snConnectService.openWithProfile($scope.profile);
                };
            }
        }
    });;;
    /*! RESOURCE: /scripts/sn/common/util/js_includes_util.js */
    /*! RESOURCE: /scripts/sn/common/util/_module.js */
    angular.module('sn.common.util', ['sn.common.auth']);
    angular.module('sn.util', ['sn.common.util']);;
    /*! RESOURCE: /scripts/sn/common/util/service.dateUtils.js */
    angular.module('sn.common.util').factory('dateUtils', function() {
        var dateUtils = {
            SYS_DATE_FORMAT: "yyyy-MM-dd",
            SYS_TIME_FORMAT: "HH:mm:ss",
            SYS_DATE_TIME_FORMAT: "yyyy-MM-dd HH:mm:ss",
            MONTH_NAMES: new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
            DAY_NAMES: new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'),
            LZ: function(x) {
                return (x < 0 || x > 9 ? "" : "0") + x
            },
            isDate: function(val, format) {
                var date = this.getDateFromFormat(val, format);
                if (date == 0) {
                    return false;
                }
                return true;
            },
            compareDates: function(date1, dateformat1, date2, dateformat2) {
                var d1 = this.getDateFromFormat(date1, dateformat1);
                var d2 = this.getDateFromFormat(date2, dateformat2);
                if (d1 == 0 || d2 == 0) {
                    return -1;
                } else if (d1 > d2) {
                    return 1;
                }
                return 0;
            },
            formatDateServer: function(date, format) {
                var ga = new GlideAjax("DateTimeUtils");
                ga.addParam("sysparm_name", "formatCalendarDate");
                var browserOffset = date.getTimezoneOffset() * 60000;
                var utcTime = date.getTime() - browserOffset;
                var userDateTime = utcTime - g_tz_offset;
                ga.addParam("sysparm_value", userDateTime);
                ga.getXMLWait();
                return ga.getAnswer();
            },
            formatDate: function(date, format) {
                if (format.indexOf("z") > 0)
                    return this.formatDateServer(date, format);
                format = format + "";
                var result = "";
                var i_format = 0;
                var c = "";
                var token = "";
                var y = date.getYear() + "";
                var M = date.getMonth() + 1;
                var d = date.getDate();
                var E = date.getDay();
                var H = date.getHours();
                var m = date.getMinutes();
                var s = date.getSeconds();
                var yyyy, yy, MMM, MM, dd, hh, h, mm, ss, ampm, HH, H, KK, K, kk, k;
                var value = new Object();
                value["M"] = M;
                value["MM"] = this.LZ(M);
                value["MMM"] = this.MONTH_NAMES[M + 11];
                value["NNN"] = this.MONTH_NAMES[M + 11];
                value["MMMM"] = this.MONTH_NAMES[M - 1];
                value["d"] = d;
                value["dd"] = this.LZ(d);
                value["E"] = this.DAY_NAMES[E + 7];
                value["EE"] = this.DAY_NAMES[E];
                value["H"] = H;
                value["HH"] = this.LZ(H);
                if (format.indexOf('w') != -1) {
                    var wk = date.getWeek();
                    if (wk >= 52 && M == 1) {
                        y = date.getYear();
                        y--;
                        y = y + "";
                    }
                    if (wk == 1 && M == 12) {
                        y = date.getYear();
                        y++;
                        y = y + "";
                    }
                    value["w"] = wk;
                    value["ww"] = this.LZ(wk);
                }
                var dayOfWeek = (7 + (E + 1) - (g_first_day_of_week - 1)) % 7;
                if (dayOfWeek == 0)
                    dayOfWeek = 7;
                value["D"] = dayOfWeek;
                if (y.length < 4) {
                    y = "" + (y - 0 + 1900);
                }
                value["y"] = "" + y;
                value["yyyy"] = y;
                value["yy"] = y.substring(2, 4);
                if (H == 0) {
                    value["h"] = 12;
                } else if (H > 12) {
                    value["h"] = H - 12;
                } else {
                    value["h"] = H;
                }
                value["hh"] = this.LZ(value["h"]);
                if (H > 11) {
                    value["K"] = H - 12;
                } else {
                    value["K"] = H;
                }
                value["k"] = H + 1;
                value["KK"] = this.LZ(value["K"]);
                value["kk"] = this.LZ(value["k"]);
                if (H > 11) {
                    value["a"] = "PM";
                } else {
                    value["a"] = "AM";
                }
                value["m"] = m;
                value["mm"] = this.LZ(m);
                value["s"] = s;
                value["ss"] = this.LZ(s);
                while (i_format < format.length) {
                    c = format.charAt(i_format);
                    token = "";
                    while ((format.charAt(i_format) == c) && (i_format < format.length)) {
                        token += format.charAt(i_format++);
                    }
                    if (value[token] != null) {
                        result = result + value[token];
                    } else {
                        result = result + token;
                    }
                }
                return result;
            },
            _isInteger: function(val) {
                var digits = "1234567890";
                for (var i = 0; i < val.length; i++) {
                    if (digits.indexOf(val.charAt(i)) == -1) {
                        return false;
                    }
                }
                return true;
            },
            _getInt: function(str, i, minlength, maxlength) {
                for (var x = maxlength; x >= minlength; x--) {
                    var token = str.substring(i, i + x);
                    if (token.length < minlength) {
                        return null;
                    }
                    if (this._isInteger(token)) {
                        return token;
                    }
                }
                return null;
            },
            getDateFromFormat: function(val, format) {
                val = val + "";
                format = format + "";
                var i_val = 0;
                var i_format = 0;
                var c = "";
                var token = "";
                var token2 = "";
                var x, y;
                var now = new Date();
                var year = now.getYear();
                var month = now.getMonth() + 1;
                var date = 0;
                var hh = now.getHours();
                var mm = now.getMinutes();
                var ss = now.getSeconds();
                var ampm = "";
                var week = false;
                while (i_format < format.length) {
                    c = format.charAt(i_format);
                    token = "";
                    while ((format.charAt(i_format) == c) && (i_format < format.length)) {
                        token += format.charAt(i_format++);
                    }
                    if (token == "yyyy" || token == "yy" || token == "y") {
                        if (token == "yyyy") {
                            x = 4;
                            y = 4;
                        }
                        if (token == "yy") {
                            x = 2;
                            y = 2;
                        }
                        if (token == "y") {
                            x = 2;
                            y = 4;
                        }
                        year = this._getInt(val, i_val, x, y);
                        if (year == null) {
                            return 0;
                        }
                        i_val += year.length;
                        if (year.length == 2) {
                            if (year > 70) {
                                year = 1900 + (year - 0);
                            } else {
                                year = 2000 + (year - 0);
                            }
                        }
                    } else if (token == "MMM" || token == "NNN") {
                        month = 0;
                        for (var i = 0; i < this.MONTH_NAMES.length; i++) {
                            var month_name = this.MONTH_NAMES[i];
                            if (val.substring(i_val, i_val + month_name.length).toLowerCase() == month_name.toLowerCase()) {
                                if (token == "MMM" || (token == "NNN" && i > 11)) {
                                    month = i + 1;
                                    if (month > 12) {
                                        month -= 12;
                                    }
                                    i_val += month_name.length;
                                    break;
                                }
                            }
                        }
                        if ((month < 1) || (month > 12)) {
                            return 0;
                        }
                    } else if (token == "EE" || token == "E") {
                        for (var i = 0; i < this.DAY_NAMES.length; i++) {
                            var day_name = this.DAY_NAMES[i];
                            if (val.substring(i_val, i_val + day_name.length).toLowerCase() == day_name.toLowerCase()) {
                                if (week) {
                                    if (i == 0 || i == 7)
                                        date += 6;
                                    else if (i == 2 || i == 9)
                                        date += 1;
                                    else if (i == 3 || i == 10)
                                        date += 2;
                                    else if (i == 4 || i == 11)
                                        date += 3;
                                    else if (i == 5 || i == 12)
                                        date += 4;
                                    else if (i == 6 || i == 13)
                                        date += 5;
                                }
                                i_val += day_name.length;
                                break;
                            }
                        }
                    } else if (token == "MM" || token == "M") {
                        month = this._getInt(val, i_val, token.length, 2);
                        if (month == null || (month < 1) || (month > 12)) {
                            return 0;
                        }
                        i_val += month.length;
                    } else if (token == "dd" || token == "d") {
                        date = this._getInt(val, i_val, token.length, 2);
                        if (date == null || (date < 1) || (date > 31)) {
                            return 0;
                        }
                        i_val += date.length;
                    } else if (token == "hh" || token == "h") {
                        hh = this._getInt(val, i_val, token.length, 2);
                        if (hh == null || (hh < 1) || (hh > 12)) {
                            return 0;
                        }
                        i_val += hh.length;
                    } else if (token == "HH" || token == "H") {
                        hh = this._getInt(val, i_val, token.length, 2);
                        if (hh == null || (hh < 0) || (hh > 23)) {
                            return 0;
                        }
                        i_val += hh.length;
                    } else if (token == "KK" || token == "K") {
                        hh = this._getInt(val, i_val, token.length, 2);
                        if (hh == null || (hh < 0) || (hh > 11)) {
                            return 0;
                        }
                        i_val += hh.length;
                    } else if (token == "kk" || token == "k") {
                        hh = this._getInt(val, i_val, token.length, 2);
                        if (hh == null || (hh < 1) || (hh > 24)) {
                            return 0;
                        }
                        i_val += hh.length;
                        hh--;
                    } else if (token == "mm" || token == "m") {
                        mm = this._getInt(val, i_val, token.length, 2);
                        if (mm == null || (mm < 0) || (mm > 59)) {
                            return 0;
                        }
                        i_val += mm.length;
                    } else if (token == "ss" || token == "s") {
                        ss = this._getInt(val, i_val, token.length, 2);
                        if (ss == null || (ss < 0) || (ss > 59)) {
                            return 0;
                        }
                        i_val += ss.length;
                    } else if (token == "a") {
                        if (val.substring(i_val, i_val + 2).toLowerCase() == "am") {
                            ampm = "AM";
                        } else if (val.substring(i_val, i_val + 2).toLowerCase() == "pm") {
                            ampm = "PM";
                        } else {
                            return 0;
                        }
                        i_val += 2;
                    } else if (token == "w" || token == "ww") {
                        var weekNum = this._getInt(val, i_val, token.length, 2);
                        week = true;
                        if (weekNum != null) {
                            var temp = new Date(year, 0, 1, 0, 0, 0);
                            temp.setWeek(parseInt(weekNum, 10));
                            year = temp.getFullYear();
                            month = temp.getMonth() + 1;
                            date = temp.getDate();
                        }
                        weekNum += "";
                        i_val += weekNum.length;
                    } else if (token == "D") {
                        if (week) {
                            var day = this._getInt(val, i_val, token.length, 1);
                            if ((day == null) || (day <= 0) || (day > 7))
                                return 0;
                            var temp = new Date(year, month - 1, date, hh, mm, ss);
                            var dayOfWeek = temp.getDay();
                            day = parseInt(day, 10);
                            day = (day + g_first_day_of_week - 1) % 7;
                            if (day == 0)
                                day = 7;
                            day--;
                            if (day < dayOfWeek)
                                day = 7 - (dayOfWeek - day);
                            else
                                day -= dayOfWeek;
                            if (day > 0) {
                                temp.setDate(temp.getDate() + day);
                                year = temp.getFullYear();
                                month = temp.getMonth() + 1;
                                date = temp.getDate();
                            }
                            i_val++;
                        }
                    } else if (token == "z")
                        i_val += 3;
                    else {
                        if (val.substring(i_val, i_val + token.length) != token) {
                            return 0;
                        } else {
                            i_val += token.length;
                        }
                    }
                }
                if (i_val != val.length) {
                    return 0;
                }
                if (month == 2) {
                    if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
                        if (date > 29) {
                            return 0;
                        }
                    } else {
                        if (date > 28) {
                            return 0;
                        }
                    }
                }
                if ((month == 4) || (month == 6) || (month == 9) || (month == 11)) {
                    if (date > 30) {
                        return 0;
                    }
                }
                if (hh < 12 && ampm == "PM") {
                    hh = hh - 0 + 12;
                } else if (hh > 11 && ampm == "AM") {
                    hh -= 12;
                }
                var newdate = new Date(year, month - 1, date, hh, mm, ss);
                return newdate.getTime();
            },
            parseDate: function(val) {
                var preferEuro = (arguments.length == 2) ? arguments[1] : false;
                generalFormats = new Array('y-M-d', 'MMM d, y', 'MMM d,y', 'y-MMM-d', 'd-MMM-y', 'MMM d');
                monthFirst = new Array('M/d/y', 'M-d-y', 'M.d.y', 'MMM-d', 'M/d', 'M-d');
                dateFirst = new Array('d/M/y', 'd-M-y', 'd.M.y', 'd-MMM', 'd/M', 'd-M');
                yearFirst = new Array('yyyyw.F', 'yyw.F');
                var checkList = new Array('generalFormats', preferEuro ? 'dateFirst' : 'monthFirst', preferEuro ? 'monthFirst' : 'dateFirst', 'yearFirst');
                var d = null;
                for (var i = 0; i < checkList.length; i++) {
                    var l = window[checkList[i]];
                    for (var j = 0; j < l.length; j++) {
                        d = this.getDateFromFormat(val, l[j]);
                        if (d != 0) {
                            return new Date(d);
                        }
                    }
                }
                return null;
            }
        };
        Date.prototype.getWeek = function() {
            var newYear = new Date(this.getFullYear(), 0, 1);
            var day = newYear.getDay() - (g_first_day_of_week - 1);
            day = (day >= 0 ? day : day + 7);
            var dayNum = Math.floor((this.getTime() - newYear.getTime() - (this.getTimezoneOffset() - newYear.getTimezoneOffset()) * 60000) / 86400000) + 1;
            var weekNum;
            if (day < 4) {
                weekNum = Math.floor((dayNum + day - 1) / 7) + 1;
                if (weekNum > 52)
                    weekNum = this._checkNextYear(weekNum);
                return weekNum;
            }
            weekNum = Math.floor((dayNum + day - 1) / 7);
            if (weekNum < 1)
                weekNum = this._lastWeekOfYear();
            else if (weekNum > 52)
                weekNum = this._checkNextYear(weekNum);
            return weekNum;
        };
        Date.prototype._lastWeekOfYear = function() {
            var newYear = new Date(this.getFullYear() - 1, 0, 1);
            var endOfYear = new Date(this.getFullYear() - 1, 11, 31);
            var day = newYear.getDay() - (g_first_day_of_week - 1);
            var dayNum = Math.floor((endOfYear.getTime() - newYear.getTime() - (endOfYear.getTimezoneOffset() - newYear.getTimezoneOffset()) * 60000) / 86400000) + 1;
            return day < 4 ? Math.floor((dayNum + day - 1) / 7) + 1 : Math.floor((dayNum + day - 1) / 7);
        };
        Date.prototype._checkNextYear = function() {
            var nYear = new Date(this.getFullYear() + 1, 0, 1);
            var nDay = nYear.getDay() - (g_first_day_of_week - 1);
            nDay = nDay >= 0 ? nDay : nDay + 7;
            return nDay < 4 ? 1 : 53;
        };
        Date.prototype.setWeek = function(weekNum) {
            weekNum--;
            var startOfYear = new Date(this.getFullYear(), 0, 1);
            var day = startOfYear.getDay() - (g_first_day_of_week - 1);
            if (day > 0 && day < 4) {
                this.setFullYear(startOfYear.getFullYear() - 1);
                this.setDate(31 - day + 1);
                this.setMonth(11);
            } else if (day > 3)
                this.setDate(startOfYear.getDate() + (7 - day));
            this.setDate(this.getDate() + (7 * weekNum));
        };
        return dateUtils;
    });
    /*! RESOURCE: /scripts/sn/common/util/service.debounceFn.js */
    angular.module("sn.common.util").service("debounceFn", function() {
        "use strict";
    
        function debounce(func, wait, immediate) {
            var timeout;
            return function() {
                var context = this,
                    args = arguments;
                var later = function() {
                    timeout = null;
                    if (!immediate) func.apply(context, args);
                };
                var callNow = immediate && !timeout;
                clearTimeout(timeout);
                timeout = setTimeout(later, wait);
                if (callNow) func.apply(context, args);
            };
        }
        return {
            debounce: debounce
        }
    });;
    /*! RESOURCE: /scripts/sn/common/util/factory.unwrappedHTTPPromise.js */
    angular.module('sn.common.util').factory("unwrappedHTTPPromise", function($q) {
        "use strict";
    
        function isGenericPromise(promise) {
            return (typeof promise.then === "function" &&
                promise.success === undefined &&
                promise.error === undefined);
        }
        return function(httpPromise) {
            if (isGenericPromise(httpPromise))
                return httpPromise;
            var deferred = $q.defer();
            httpPromise.success(function(data) {
                deferred.resolve(data);
            }).error(function(data, status) {
                deferred.reject({
                    data: data,
                    status: status
                })
            });
            return deferred.promise;
        };
    });;
    /*! RESOURCE: /scripts/sn/common/util/service.urlTools.js */
    angular.module('sn.common.util').constant('angularProcessorUrl', 'angular.do?sysparm_type=');
    angular.module('sn.common.util').factory("urlTools", function(getTemplateUrl, angularProcessorUrl) {
        "use strict";
    
        function getPartialURL(name, parameters) {
            var url = getTemplateUrl(name);
            if (parameters) {
                if (typeof parameters !== 'string') {
                    parameters = encodeURIParameters(parameters);
                }
                if (parameters.length) {
                    url += "&" + parameters;
                }
            }
            if (window.NOW && window.NOW.ng_cache_defeat)
                url += "&t=" + new Date().getTime();
            return url;
        }
    
        function getURL(name, parameters) {
            if (parameters && typeof parameters === 'object')
                return urlFor(name, parameters);
            var url = angularProcessorUrl;
            url += name;
            if (parameters)
                url += "&" + parameters;
            return url;
        }
    
        function urlFor(route, parameters) {
            var p = encodeURIParameters(parameters);
            return angularProcessorUrl + route + (p.length ? '&' + p : '');
        }
    
        function getPropertyURL(name) {
            var url = angularProcessorUrl + "get_property&name=" + name;
            url += "&t=" + new Date().getTime();
            return url;
        }
    
        function encodeURIParameters(parameters) {
            var s = [];
            for (var parameter in parameters) {
                if (parameters.hasOwnProperty(parameter)) {
                    var key = encodeURIComponent(parameter);
                    var value = parameters[parameter] ? encodeURIComponent(parameters[parameter]) : '';
                    s.push(key + "=" + value);
                }
            }
            return s.join('&');
        }
    
        function parseQueryString(qs) {
            qs = qs || '';
            if (qs.charAt(0) === '?') {
                qs = qs.substr(1);
            }
            var a = qs.split('&');
            if (a === "") {
                return {};
            }
            if (a && a[0].indexOf('http') != -1)
                a[0] = a[0].split("?")[1];
            var b = {};
            for (var i = 0; i < a.length; i++) {
                var p = a[i].split('=', 2);
                if (p.length == 1) {
                    b[p[0]] = "";
                } else {
                    b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
                }
            }
            return b;
        }
        return {
            getPartialURL: getPartialURL,
            getURL: getURL,
            urlFor: urlFor,
            getPropertyURL: getPropertyURL,
            encodeURIParameters: encodeURIParameters,
            parseQueryString: parseQueryString
        };
    });;
    /*! RESOURCE: /scripts/sn/common/util/service.getTemplateUrl.js */
    angular.module('sn.common.util').provider('getTemplateUrl', function(angularProcessorUrl) {
        'use strict';
        var _handlerId = 0;
        var _handlers = {};
        this.registerHandler = function(handler) {
            var registeredId = _handlerId;
            _handlers[_handlerId] = handler;
            _handlerId++;
            return function() {
                delete _handlers[registeredId];
            };
        };
        this.$get = function() {
            return getTemplateUrl;
        };
    
        function getTemplateUrl(templatePath) {
            if (_handlerId > 0) {
                var path;
                var handled = false;
                angular.forEach(_handlers, function(handler) {
                    if (!handled) {
                        var handlerPath = handler(templatePath);
                        if (typeof handlerPath !== 'undefined') {
                            path = handlerPath;
                            handled = true;
                        }
                    }
                });
                if (handled) {
                    return path;
                }
            }
            return angularProcessorUrl + 'get_partial&name=' + templatePath;
        }
    });;
    /*! RESOURCE: /scripts/sn/common/util/service.snTabActivity.js */
    angular.module("sn.common.util").service("snTabActivity", function($window, $timeout, $rootElement, $document) {
        "use strict";
        var activeEvents = ["keydown", "DOMMouseScroll", "mousewheel", "mousedown", "touchstart", "mousemove", "mouseenter", "input", "focus", "scroll"],
            defaultIdle = 75000,
            isPrimary = true,
            idleTime = 0,
            isVisible = true,
            idleTimeout = void(0),
            pageIdleTimeout = void(0),
            hasActed = false,
            appName = $rootElement.attr('ng-app') || "",
            storageKey = "sn.tabs." + appName + ".activeTab";
        var callbacks = {
            "tab.primary": [],
            "tab.secondary": [],
            "activity.active": [],
            "activity.idle": [{
                delay: defaultIdle,
                cb: function() {}
            }]
        };
        $window.tabGUID = $window.tabGUID || createGUID();
    
        function setAppName(an) {
            appName = an;
            storageKey = "sn.tabs." + appName + ".activeTab";
            makePrimary(true);
        }
    
        function createGUID(l) {
            l = l || 32;
            var strResult = '';
            while (strResult.length < l)
                strResult += (((1 + Math.random() + new Date().getTime()) * 0x10000) | 0).toString(16).substring(1);
            return strResult.substr(0, l);
        }
    
        function ngObjectIndexOf(arr, obj) {
            for (var i = 0, len = arr.length; i < len; i++)
                if (angular.equals(arr[i], obj))
                    return i;
            return -1;
        }
        var detectedApi,
            apis = [{
                eventName: 'visibilitychange',
                propertyName: 'hidden'
            }, {
                eventName: 'mozvisibilitychange',
                propertyName: 'mozHidden'
            }, {
                eventName: 'msvisibilitychange',
                propertyName: 'msHidden'
            }, {
                eventName: 'webkitvisibilitychange',
                propertyName: 'webkitHidden'
            }];
        apis.some(function(api) {
            if (angular.isDefined($document[0][api.propertyName])) {
                detectedApi = api;
                return true;
            }
        });
        if (detectedApi)
            $document.on(detectedApi.eventName, function() {
                if (!$document[0][detectedApi.propertyName]) {
                    makePrimary();
                    isVisible = true;
                } else {
                    if (!idleTimeout && !idleTime)
                        waitForIdle(0);
                    isVisible = false;
                }
            });
        angular.element($window).on({
            "mouseleave": function(e) {
                var destination = angular.isUndefined(e.toElement) ? e.relatedTarget : e.toElement;
                if (destination === null && $document[0].hasFocus()) {
                    waitForIdle(0);
                }
            },
            "storage": function(e) {
                if (e.originalEvent.key !== storageKey)
                    return;
                if ($window.localStorage.getItem(storageKey) !== $window.tabGUID)
                    makeSecondary();
            }
        });
    
        function waitForIdle(index, delayOffset) {
            var callback = callbacks['activity.idle'][index];
            var numCallbacks = callbacks['activity.idle'].length;
            delayOffset = delayOffset || callback.delay;
            angular.element($window).off(activeEvents.join(".snTabActivity "));
            angular.element($window).one(activeEvents.join(".snTabActivity "), setActive);
            if (index >= numCallbacks)
                return;
            if (idleTimeout)
                $timeout.cancel(idleTimeout);
            idleTimeout = $timeout(function() {
                idleTime = callback.delay;
                callback.cb();
                $timeout.cancel(idleTimeout);
                idleTimeout = void(0);
                angular.element($window).off(activeEvents.join(".snTabActivity "));
                angular.element($window).one(activeEvents.join(".snTabActivity "), setActive);
                for (var i = index + 1; i < numCallbacks; i++) {
                    var nextDelay = callbacks['activity.idle'][i].delay;
                    if (nextDelay <= callback.delay)
                        callbacks['activity.idle'][i].cb();
                    else {
                        waitForIdle(i, nextDelay - callback.delay);
                        break;
                    }
                }
            }, delayOffset, false);
        }
    
        function setActive() {
            angular.element($window).off(activeEvents.join(".snTabActivity "));
            if (idleTimeout) {
                $timeout.cancel(idleTimeout);
                idleTimeout = void(0);
            }
            var activeCallbacks = callbacks['activity.active'];
            activeCallbacks.some(function(callback) {
                if (callback.delay <= idleTime)
                    callback.cb();
                else
                    return true;
            });
            idleTime = 0;
            makePrimary();
            if (pageIdleTimeout) {
                $timeout.cancel(pageIdleTimeout);
                pageIdleTimeout = void(0);
            }
            var minDelay = callbacks['activity.idle'][0].delay;
            hasActed = false;
            if (!pageIdleTimeout)
                pageIdleTimeout = $timeout(pageIdleHandler, minDelay, false);
            listenForActivity();
        }
    
        function pageIdleHandler() {
            if (idleTimeout)
                return;
            var minDelay = callbacks['activity.idle'][0].delay;
            if (hasActed) {
                hasActed = false;
                if (pageIdleTimeout)
                    $timeout.cancel(pageIdleTimeout);
                pageIdleTimeout = $timeout(pageIdleHandler, minDelay, false);
                listenForActivity();
                return;
            }
            var delayOffset = minDelay;
            if (callbacks['activity.idle'].length > 1)
                delayOffset = callbacks['activity.idle'][1].delay - minDelay;
            idleTime = minDelay;
            callbacks['activity.idle'][0].cb();
            waitForIdle(1, delayOffset);
            pageIdleTimeout = void(0);
        }
    
        function listenForActivity() {
            angular.element($window).off(activeEvents.join(".snTabActivity "));
            angular.element($window).one(activeEvents.join(".snTabActivity "), onActivity);
            angular.element("#gsft_main").on("load.snTabActivity", function() {
                var src = angular.element(this).attr('src');
                if (src.indexOf("/") == 0 || src.indexOf($window.location.origin) == 0 || src.indexOf('http') == -1) {
                    var iframeWindow = this.contentWindow ? this.contentWindow : this.contentDocument.defaultView;
                    angular.element(iframeWindow).off(activeEvents.join(".snTabActivity "));
                    angular.element(iframeWindow).one(activeEvents.join(".snTabActivity "), onActivity);
                }
            });
            angular.element('iframe').each(function(idx, iframe) {
                var src = angular.element(iframe).attr('src');
                if (!src)
                    return;
                if (src.indexOf("/") == 0 || src.indexOf($window.location.origin) == 0 || src.indexOf('http') == -1) {
                    var iframeWindow = iframe.contentWindow ? iframe.contentWindow : iframe.contentDocument.defaultView;
                    angular.element(iframeWindow).off(activeEvents.join(".snTabActivity "));
                    angular.element(iframeWindow).one(activeEvents.join(".snTabActivity "), onActivity);
                }
            });
        }
    
        function onActivity() {
            hasActed = true;
            makePrimary();
        }
    
        function makePrimary(initial) {
            var oldGuid = $window.localStorage.getItem(storageKey);
            isPrimary = true;
            isVisible = true;
            $timeout.cancel(idleTimeout);
            idleTimeout = void(0);
            if (canUseStorage() && oldGuid !== $window.tabGUID && !initial)
                for (var i = 0, len = callbacks["tab.primary"].length; i < len; i++)
                    callbacks["tab.primary"][i].cb();
            try {
                $window.localStorage.setItem(storageKey, $window.tabGUID);
            } catch (ignored) {}
            if (idleTime && $document[0].hasFocus())
                setActive();
        }
    
        function makeSecondary() {
            isPrimary = false;
            isVisible = false;
            for (var i = 0, len = callbacks["tab.secondary"].length; i < len; i++)
                callbacks["tab.secondary"][i].cb();
        }
    
        function registerCallback(event, callback, scope) {
            var cbObject = angular.isObject(callback) ? callback : {
                delay: defaultIdle,
                cb: callback
            };
            if (callbacks[event]) {
                callbacks[event].push(cbObject);
                callbacks[event].sort(function(a, b) {
                    return a.delay - b.delay;
                })
            }
    
            function destroyCallback() {
                if (callbacks[event]) {
                    var pos = ngObjectIndexOf(callbacks[event], cbObject);
                    if (pos !== -1)
                        callbacks[event].splice(pos, 1);
                }
            }
            if (scope)
                scope.$on("$destroy", function() {
                    destroyCallback();
                });
            return destroyCallback;
        }
    
        function registerIdleCallback(options, onIdle, onReturn, scope) {
            var delay = options,
                onIdleDestroy,
                onReturnDestroy;
            if (angular.isObject(options)) {
                delay = options.delay;
                onIdle = options.onIdle || onIdle;
                onReturn = options.onReturn || onReturn;
                scope = options.scope || scope;
            }
            if (angular.isFunction(onIdle))
                onIdleDestroy = registerCallback("activity.idle", {
                    delay: delay,
                    cb: onIdle
                });
            else if (angular.isFunction(onReturn)) {
                onIdleDestroy = registerCallback("activity.idle", {
                    delay: delay,
                    cb: function() {}
                });
            }
            if (angular.isFunction(onReturn))
                onReturnDestroy = registerCallback("activity.active", {
                    delay: delay,
                    cb: onReturn
                });
    
            function destroyAll() {
                if (angular.isFunction(onIdleDestroy))
                    onIdleDestroy();
                if (angular.isFunction(onReturnDestroy))
                    onReturnDestroy();
            }
            if (scope)
                scope.$on("$destroy", function() {
                    destroyAll();
                });
            return destroyAll;
        }
    
        function canUseStorage() {
            var canWe = false;
            try {
                $window.localStorage.setItem(storageKey, $window.tabGUID);
                canWe = true;
            } catch (ignored) {}
            return canWe;
        }
        makePrimary(true);
        listenForActivity();
        pageIdleTimeout = $timeout(pageIdleHandler, defaultIdle, false);
        return {
            on: registerCallback,
            onIdle: registerIdleCallback,
            setAppName: setAppName,
            get isPrimary() {
                return isPrimary;
            },
            get isIdle() {
                return idleTime > 0;
            },
            get idleTime() {
                return idleTime;
            },
            get isVisible() {
                return isVisible;
            },
            get appName() {
                return appName;
            },
            get defaultIdleTime() {
                return defaultIdle
            },
            isActive: function() {
                return this.idleTime < this.defaultIdleTime && this.isVisible;
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/util/factory.ArraySynchronizer.js */
    angular.module("sn.common.util").factory("ArraySynchronizer", function() {
        'use strict';
    
        function ArraySynchronizer() {}
    
        function index(key, arr) {
            var result = {};
            var keys = [];
            result.orderedKeys = keys;
            angular.forEach(arr, function(item) {
                var keyValue = item[key];
                result[keyValue] = item;
                keys.push(keyValue);
            });
            return result;
        }
    
        function sortByKeyAndModel(arr, key, model) {
            arr.sort(function(a, b) {
                var aIndex = model.indexOf(a[key]);
                var bIndex = model.indexOf(b[key]);
                if (aIndex > bIndex)
                    return 1;
                else if (aIndex < bIndex)
                    return -1;
                return 0;
            });
        }
        ArraySynchronizer.prototype = {
            add: function(syncField, dest, source, end) {
                end = end || "bottom";
                var destIndex = index(syncField, dest);
                var sourceIndex = index(syncField, source);
                angular.forEach(sourceIndex.orderedKeys, function(key) {
                    if (destIndex.orderedKeys.indexOf(key) === -1) {
                        if (end === "bottom") {
                            dest.push(sourceIndex[key]);
                        } else {
                            dest.unshift(sourceIndex[key]);
                        }
                    }
                });
            },
            synchronize: function(syncField, dest, source, deepKeySyncArray) {
                var destIndex = index(syncField, dest);
                var sourceIndex = index(syncField, source);
                deepKeySyncArray = (typeof deepKeySyncArray === "undefined") ? [] : deepKeySyncArray;
                for (var i = destIndex.orderedKeys.length - 1; i >= 0; i--) {
                    var key = destIndex.orderedKeys[i];
                    if (sourceIndex.orderedKeys.indexOf(key) === -1) {
                        destIndex.orderedKeys.splice(i, 1);
                        dest.splice(i, 1);
                    }
                    if (deepKeySyncArray.length > 0) {
                        angular.forEach(deepKeySyncArray, function(deepKey) {
                            if (sourceIndex[key] && destIndex[key][deepKey] !== sourceIndex[key][deepKey]) {
                                destIndex[key][deepKey] = sourceIndex[key][deepKey];
                            }
                        });
                    }
                }
                angular.forEach(sourceIndex.orderedKeys, function(key) {
                    if (destIndex.orderedKeys.indexOf(key) === -1)
                        dest.push(sourceIndex[key]);
                });
                sortByKeyAndModel(dest, syncField, sourceIndex.orderedKeys);
            }
        };
        return ArraySynchronizer;
    });;
    /*! RESOURCE: /scripts/sn/common/util/directive.snBindOnce.js */
    angular.module("sn.common.util").directive("snBindOnce", function($sanitize) {
        "use strict";
        return {
            restrict: "A",
            link: function(scope, element, attrs) {
                var value = scope.$eval(attrs.snBindOnce);
                var sanitizedValue = $sanitize(value);
                element.append(sanitizedValue);
            }
        }
    });
    /*! RESOURCE: /scripts/sn/common/util/directive.snCloak.js */
    angular.module("sn.common.util").directive("snCloak", function() {
        "use strict";
        return {
            restrict: "A",
            compile: function(element, attr) {
                return function() {
                    attr.$set('snCloak', undefined);
                    element.removeClass('sn-cloak');
                }
            }
        };
    });
    /*! RESOURCE: /scripts/sn/common/util/service.md5.js */
    angular.module('sn.common.util').factory('md5', function() {
        'use strict';
        var md5cycle = function(x, k) {
            var a = x[0],
                b = x[1],
                c = x[2],
                d = x[3];
            a = ff(a, b, c, d, k[0], 7, -680876936);
            d = ff(d, a, b, c, k[1], 12, -389564586);
            c = ff(c, d, a, b, k[2], 17, 606105819);
            b = ff(b, c, d, a, k[3], 22, -1044525330);
            a = ff(a, b, c, d, k[4], 7, -176418897);
            d = ff(d, a, b, c, k[5], 12, 1200080426);
            c = ff(c, d, a, b, k[6], 17, -1473231341);
            b = ff(b, c, d, a, k[7], 22, -45705983);
            a = ff(a, b, c, d, k[8], 7, 1770035416);
            d = ff(d, a, b, c, k[9], 12, -1958414417);
            c = ff(c, d, a, b, k[10], 17, -42063);
            b = ff(b, c, d, a, k[11], 22, -1990404162);
            a = ff(a, b, c, d, k[12], 7, 1804603682);
            d = ff(d, a, b, c, k[13], 12, -40341101);
            c = ff(c, d, a, b, k[14], 17, -1502002290);
            b = ff(b, c, d, a, k[15], 22, 1236535329);
            a = gg(a, b, c, d, k[1], 5, -165796510);
            d = gg(d, a, b, c, k[6], 9, -1069501632);
            c = gg(c, d, a, b, k[11], 14, 643717713);
            b = gg(b, c, d, a, k[0], 20, -373897302);
            a = gg(a, b, c, d, k[5], 5, -701558691);
            d = gg(d, a, b, c, k[10], 9, 38016083);
            c = gg(c, d, a, b, k[15], 14, -660478335);
            b = gg(b, c, d, a, k[4], 20, -405537848);
            a = gg(a, b, c, d, k[9], 5, 568446438);
            d = gg(d, a, b, c, k[14], 9, -1019803690);
            c = gg(c, d, a, b, k[3], 14, -187363961);
            b = gg(b, c, d, a, k[8], 20, 1163531501);
            a = gg(a, b, c, d, k[13], 5, -1444681467);
            d = gg(d, a, b, c, k[2], 9, -51403784);
            c = gg(c, d, a, b, k[7], 14, 1735328473);
            b = gg(b, c, d, a, k[12], 20, -1926607734);
            a = hh(a, b, c, d, k[5], 4, -378558);
            d = hh(d, a, b, c, k[8], 11, -2022574463);
            c = hh(c, d, a, b, k[11], 16, 1839030562);
            b = hh(b, c, d, a, k[14], 23, -35309556);
            a = hh(a, b, c, d, k[1], 4, -1530992060);
            d = hh(d, a, b, c, k[4], 11, 1272893353);
            c = hh(c, d, a, b, k[7], 16, -155497632);
            b = hh(b, c, d, a, k[10], 23, -1094730640);
            a = hh(a, b, c, d, k[13], 4, 681279174);
            d = hh(d, a, b, c, k[0], 11, -358537222);
            c = hh(c, d, a, b, k[3], 16, -722521979);
            b = hh(b, c, d, a, k[6], 23, 76029189);
            a = hh(a, b, c, d, k[9], 4, -640364487);
            d = hh(d, a, b, c, k[12], 11, -421815835);
            c = hh(c, d, a, b, k[15], 16, 530742520);
            b = hh(b, c, d, a, k[2], 23, -995338651);
            a = ii(a, b, c, d, k[0], 6, -198630844);
            d = ii(d, a, b, c, k[7], 10, 1126891415);
            c = ii(c, d, a, b, k[14], 15, -1416354905);
            b = ii(b, c, d, a, k[5], 21, -57434055);
            a = ii(a, b, c, d, k[12], 6, 1700485571);
            d = ii(d, a, b, c, k[3], 10, -1894986606);
            c = ii(c, d, a, b, k[10], 15, -1051523);
            b = ii(b, c, d, a, k[1], 21, -2054922799);
            a = ii(a, b, c, d, k[8], 6, 1873313359);
            d = ii(d, a, b, c, k[15], 10, -30611744);
            c = ii(c, d, a, b, k[6], 15, -1560198380);
            b = ii(b, c, d, a, k[13], 21, 1309151649);
            a = ii(a, b, c, d, k[4], 6, -145523070);
            d = ii(d, a, b, c, k[11], 10, -1120210379);
            c = ii(c, d, a, b, k[2], 15, 718787259);
            b = ii(b, c, d, a, k[9], 21, -343485551);
            x[0] = add32(a, x[0]);
            x[1] = add32(b, x[1]);
            x[2] = add32(c, x[2]);
            x[3] = add32(d, x[3]);
        };
        var cmn = function(q, a, b, x, s, t) {
            a = add32(add32(a, q), add32(x, t));
            return add32((a << s) | (a >>> (32 - s)), b);
        };
        var ff = function(a, b, c, d, x, s, t) {
            return cmn((b & c) | ((~b) & d), a, b, x, s, t);
        };
        var gg = function(a, b, c, d, x, s, t) {
            return cmn((b & d) | (c & (~d)), a, b, x, s, t);
        };
        var hh = function(a, b, c, d, x, s, t) {
            return cmn(b ^ c ^ d, a, b, x, s, t);
        };
        var ii = function(a, b, c, d, x, s, t) {
            return cmn(c ^ (b | (~d)), a, b, x, s, t);
        };
        var md51 = function(s) {
            var txt = '';
            var n = s.length,
                state = [1732584193, -271733879, -1732584194, 271733878],
                i;
            for (i = 64; i <= s.length; i += 64) {
                md5cycle(state, md5blk(s.substring(i - 64, i)));
            }
            s = s.substring(i - 64);
            var tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
            for (i = 0; i < s.length; i++)
                tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
            tail[i >> 2] |= 0x80 << ((i % 4) << 3);
            if (i > 55) {
                md5cycle(state, tail);
                for (i = 0; i < 16; i++) tail[i] = 0;
            }
            tail[14] = n * 8;
            md5cycle(state, tail);
            return state;
        };
        var md5blk = function(s) {
            var md5blks = [],
                i;
            for (i = 0; i < 64; i += 4) {
                md5blks[i >> 2] = s.charCodeAt(i) +
                    (s.charCodeAt(i + 1) << 8) +
                    (s.charCodeAt(i + 2) << 16) +
                    (s.charCodeAt(i + 3) << 24);
            }
            return md5blks;
        };
        var hex_chr = '0123456789abcdef'.split('');
        var rhex = function(n) {
            var s = '',
                j = 0;
            for (; j < 4; j++)
                s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] +
                hex_chr[(n >> (j * 8)) & 0x0F];
            return s;
        };
        var hex = function(x) {
            for (var i = 0; i < x.length; i++)
                x[i] = rhex(x[i]);
            return x.join('');
        };
        var add32 = function(a, b) {
            return (a + b) & 0xFFFFFFFF;
        };
        return function(s) {
            return hex(md51(s));
        };
    });;
    /*! RESOURCE: /scripts/sn/common/util/service.priorityQueue.js */
    angular.module('sn.common.util').factory('priorityQueue', function() {
        'use strict';
        return function(comparator) {
            var items = [];
            var compare = comparator || function(a, b) {
                return a - b;
            };
            var swap = function(a, b) {
                var temp = items[a];
                items[a] = items[b];
                items[b] = temp;
            };
            var bubbleUp = function(pos) {
                var parent;
                while (pos > 0) {
                    parent = (pos - 1) >> 1;
                    if (compare(items[pos], items[parent]) >= 0)
                        break;
                    swap(parent, pos);
                    pos = parent;
                }
            };
            var bubbleDown = function(pos) {
                var left, right, min, last = items.length - 1;
                while (true) {
                    left = (pos << 1) + 1;
                    right = left + 1;
                    min = pos;
                    if (left <= last && compare(items[left], items[min]) < 0)
                        min = left;
                    if (right <= last && compare(items[right], items[min]) < 0)
                        min = right;
                    if (min === pos)
                        break;
                    swap(min, pos);
                    pos = min;
                }
            };
            return {
                add: function(item) {
                    items.push(item);
                    bubbleUp(items.length - 1);
                },
                poll: function() {
                    var first = items[0],
                        last = items.pop();
                    if (items.length > 0) {
                        items[0] = last;
                        bubbleDown(0);
                    }
                    return first;
                },
                peek: function() {
                    return items[0];
                },
                clear: function() {
                    items = [];
                },
                inspect: function() {
                    return angular.toJson(items, true);
                },
                get size() {
                    return items.length;
                },
                get all() {
                    return items;
                },
                set comparator(fn) {
                    compare = fn;
                }
            };
        };
    });;
    /*! RESOURCE: /scripts/sn/common/util/service.snResource.js */
    angular.module('sn.common.util').factory('snResource', function($http, $q, priorityQueue, md5) {
        'use strict';
        var methods = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'jsonp', 'trace'],
            queue = priorityQueue(function(a, b) {
                return a.timestamp - b.timestamp;
            }),
            resource = {},
            pendingRequests = [],
            inFlightRequests = [];
        return function() {
            var requestInterceptors = $http.defaults.transformRequest,
                responseInterceptors = $http.defaults.transformResponse;
            var next = function() {
                var request = queue.peek();
                pendingRequests.shift();
                inFlightRequests.push(request.hash);
                $http(request.config).then(function(response) {
                    request.deferred.resolve(response);
                }, function(reason) {
                    request.deferred.reject(reason);
                }).finally(function() {
                    queue.poll();
                    inFlightRequests.shift();
                    if (queue.size > 0)
                        next();
                });
            };
            angular.forEach(methods, function(method) {
                resource[method] = function(url, data) {
                    var deferredRequest = $q.defer(),
                        promise = deferredRequest.promise,
                        deferredAbort = $q.defer(),
                        config = {
                            method: method,
                            url: url,
                            data: data,
                            transformRequest: requestInterceptors,
                            transformResponse: responseInterceptors,
                            timeout: deferredAbort.promise
                        },
                        hash = md5(JSON.stringify(config));
                    pendingRequests.push(hash);
                    queue.add({
                        config: config,
                        deferred: deferredRequest,
                        timestamp: Date.now(),
                        hash: hash
                    });
                    if (queue.size === 1)
                        next();
                    promise.abort = function() {
                        deferredAbort.resolve('Request cancelled');
                    };
                    return promise;
                };
            });
            resource.addRequestInterceptor = function(fn) {
                requestInterceptors = requestInterceptors.concat([fn]);
            };
            resource.addResponseInterceptor = function(fn) {
                responseInterceptors = responseInterceptors.concat([fn]);
            };
            resource.queueSize = function() {
                return queue.size;
            };
            resource.queuedRequests = function() {
                return queue.all;
            };
            return resource;
        };
    });;
    /*! RESOURCE: /scripts/sn/common/util/service.snConnect.js */
    angular.module("sn.common.util").service("snConnectService", function($http, snCustomEvent) {
        "use strict";
        var connectPaths = ["/$c.do", "/$chat.do"];
    
        function canOpenInFrameset() {
            return window.top.NOW.collaborationFrameset;
        }
    
        function isInConnect() {
            var parentPath = getParentPath();
            return connectPaths.some(function(path) {
                return parentPath == path;
            });
        }
    
        function getParentPath() {
            try {
                return window.top.location.pathname;
            } catch (IGNORED) {
                return "";
            }
        }
    
        function openWithProfile(profile) {
            if (isInConnect() || canOpenInFrameset())
                snCustomEvent.fireTop('chat:open_conversation', profile);
            else
                window.open("$c.do#/with/" + profile.sys_id, "_blank");
        }
        return {
            openWithProfile: openWithProfile
        }
    });;
    /*! RESOURCE: /scripts/sn/common/util/snPolyfill.js */
    (function() {
        "use strict";
        polyfill(String.prototype, 'startsWith', function(prefix) {
            return this.indexOf(prefix) === 0;
        });
        polyfill(String.prototype, 'endsWith', function(suffix) {
            return this.indexOf(suffix, this.length - suffix.length) !== -1;
        });
        polyfill(Number, 'isNaN', function(value) {
            return value !== value;
        });
        polyfill(window, 'btoa', function(input) {
            var str = String(input);
            var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
            for (
                var block, charCode, idx = 0, map = chars, output = ''; str.charAt(idx | 0) || (map = '=', idx % 1); output += map.charAt(63 & block >> 8 - idx % 1 * 8)
            ) {
                charCode = str.charCodeAt(idx += 3 / 4);
                if (charCode > 0xFF) {
                    throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");
                }
                block = block << 8 | charCode;
            }
            return output;
        });
    
        function polyfill(obj, slot, fn) {
            if (obj[slot] === void(0)) {
                obj[slot] = fn;
            }
        }
        window.console = window.console || {
            log: function() {}
        };
    })();;
    /*! RESOURCE: /scripts/sn/common/util/directive.snFocus.js */
    angular.module('sn.common.util').directive('snFocus', function($timeout) {
        'use strict';
        return function(scope, element, attrs) {
            scope.$watch(attrs.snFocus, function(value) {
                if (value !== true)
                    return;
                $timeout(function() {
                    element[0].focus();
                });
            });
        };
    });;
    /*! RESOURCE: /scripts/sn/common/util/directive.snResizeHeight.js */
    angular.module('sn.common.util').directive('snResizeHeight', function($timeout) {
        "use strict";
        return {
            restrict: 'A',
            link: function(scope, elem, attrs) {
                var typographyStyles = [
                    'fontFamily',
                    'fontSize',
                    'fontWeight',
                    'fontStyle',
                    'letterSpacing',
                    'textTransform',
                    'wordSpacing',
                    'textIndent'
                ];
                var maxHeight = parseInt(elem.css('max-height'), 10) || 0;
                var offset = 0;
                if (elem.css('box-sizing') === 'border-box' || elem.css('-moz-box-sizing') === 'border-box' || elem.css('-webkit-box-sizing') === 'border-box')
                    offset = elem.outerHeight() - elem.height();
                var styles = {};
                angular.forEach(typographyStyles, function(val) {
                    styles[val] = elem.css(val);
                });
                var $clone = angular.element('<textarea rows="1" tabindex="-1" style="position:absolute; top:-999px; left:0; right:auto; bottom:auto; border:0; padding: 0; -moz-box-sizing:content-box; -webkit-box-sizing:content-box; box-sizing:content-box; word-wrap:break-word; height:0 !important; min-height:0 !important; overflow:hidden; transition:none; -webkit-transition:none; -moz-transition:none;"></textarea>');
                $clone.css(styles);
                $timeout(function() {
                    angular.element(document.body).append($clone);
                    reSize();
                }, 0, false);
                if (window.chrome) {
                    var width = elem[0].style.width;
                    elem[0].style.width = '0px';
                    var ignore = elem[0].offsetWidth;
                    elem[0].style.width = width;
                }
    
                function reSize() {
                    if (!setWidth())
                        return;
                    if (!elem[0].value && attrs['placeholder'])
                        $clone[0].value = attrs['placeholder'] || '';
                    else
                        $clone[0].value = elem[0].value;
                    $clone[0].scrollTop = 0;
                    $clone[0].scrollTop = 9e4;
                    var newHeight = $clone[0].scrollTop;
                    if (maxHeight && newHeight > maxHeight) {
                        newHeight = maxHeight;
                        elem[0].style.overflow = "auto";
                    } else
                        elem[0].style.overflow = "hidden";
                    newHeight += offset;
                    elem[0].style.height = newHeight + "px";
                }
    
                function setWidth() {
                    var width;
                    var style = window.getComputedStyle ? window.getComputedStyle(elem[0], null) : false;
                    if (style) {
                        width = elem[0].getBoundingClientRect().width;
                        if (width === 0 || typeof width !== 'number') {
                            if (style.width.length && style.width[style.width.length - 1] === '%') {
                                $timeout(reSize, 0, false);
                                return false;
                            }
                            width = parseInt(style.width, 10);
                        }
                        angular.forEach(['paddingLeft', 'paddingRight', 'borderLeftWidth', 'borderRightWidth'], function(val) {
                            width -= parseInt(style[val], 10);
                        });
                    } else {
                        width = Math.max(elem.width(), 0);
                    }
                    $clone[0].style.width = width + 'px';
                    return true;
                }
                scope.$watch(
                    function() {
                        return elem[0].value
                    },
                    function(newValue, oldValue) {
                        if (newValue === oldValue)
                            return;
                        reSize();
                    }
                );
                elem.on('input.resize', reSize);
                if (attrs['snResizeHeight'] == "trim") {
                    elem.on('blur', function() {
                        elem.val(elem.val().trim());
                        reSize();
                    });
                }
                scope.$on('$destroy', function() {
                    $clone.remove();
                });
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/util/directive.snBlurOnEnter.js */
    angular.module('sn.common.util').directive('snBlurOnEnter', function() {
        'use strict';
        return function(scope, element) {
            element.bind("keydown keypress", function(event) {
                if (event.which !== 13)
                    return;
                element.blur();
                event.preventDefault();
            });
        };
    });;
    /*! RESOURCE: /scripts/sn/common/util/directive.snStickyHeaders.js */
    angular.module('sn.common.util').directive('snStickyHeaders', function() {
        "use strict";
        return {
            restrict: 'A',
            transclude: false,
            replace: false,
            link: function(scope, element, attrs) {
                element.addClass('sticky-headers');
                var containers;
                var scrollContainer = element.find('[sn-sticky-scroll-container]');
                scrollContainer.addClass('sticky-scroll-container');
    
                function refreshHeaders() {
                    if (attrs.snStickyHeaders !== 'false') {
                        angular.forEach(containers, function(container) {
                            var stickyContainer = angular.element(container);
                            var stickyHeader = stickyContainer.find('[sn-sticky-header]');
                            var stickyOffset = stickyContainer.position().top + stickyContainer.outerHeight();
                            stickyContainer.addClass('sticky-container');
                            if (stickyOffset < stickyContainer.outerHeight() && stickyOffset > -stickyHeader.outerHeight()) {
                                stickyContainer.css('padding-top', stickyHeader.outerHeight());
                                stickyHeader.css('width', stickyHeader.outerWidth());
                                stickyHeader.removeClass('sticky-header-disabled').addClass('sticky-header-enabled');
                            } else {
                                stickyContainer.css('padding-top', '');
                                stickyHeader.css('width', '');
                                stickyHeader.removeClass('sticky-header-enabled').addClass('sticky-header-disabled');
                            }
                        });
                    } else {
                        element.find('[sn-sticky-container]').removeClass('sticky-container');
                        element.find('[sn-sticky-container]').css('padding-top', '');
                        element.find('[sn-sticky-header]').css('width', '');
                        element.find('[sn-sticky-header]').removeClass('sticky-header-enabled').addClass('sticky-header-disabled');
                    }
                }
                scope.$watch(function() {
                    scrollContainer.find('[sn-sticky-header]').addClass('sticky-header');
                    containers = element.find('[sn-sticky-container]');
                    return attrs.snStickyHeaders;
                }, refreshHeaders);
                scope.$watch(function() {
                    return scrollContainer[0].scrollHeight;
                }, refreshHeaders);
                scrollContainer.on('scroll', refreshHeaders);
            }
        };
    });;;
    /*! RESOURCE: /scripts/sn/common/ui/js_includes_ui.js */
    /*! RESOURCE: /scripts/sn/common/ui/_module.js */
    angular.module('sn.common.ui', ['sn.common.messaging']);;
    /*! RESOURCE: /scripts/sn/common/ui/popover/js_includes_ui_popover.js */
    /*! RESOURCE: /scripts/sn/common/ui/popover/_module.js */
    angular.module('sn.common.ui.popover', []);;
    /*! RESOURCE: /scripts/sn/common/ui/popover/directive.snBindPopoverSelection.js */
    angular.module('sn.common.ui.popover').directive('snBindPopoverSelection', function(snCustomEvent) {
        "use strict";
        return {
            restrict: "A",
            controller: function($scope, $element, $attrs, snCustomEvent) {
                snCustomEvent.observe('list.record_select', recordSelectDataHandler);
    
                function recordSelectDataHandler(data, event) {
                    if (!data || !event)
                        return;
                    event.stopPropagation();
                    var ref = ($scope.field) ? $scope.field.ref : $attrs.ref;
                    if (data.ref === ref) {
                        if (window.g_form) {
                            if ($attrs.addOption) {
                                addGlideListChoice('select_0' + $attrs.ref, data.value, data.displayValue);
                            } else {
                                var fieldValue = typeof $attrs.ref === 'undefined' ? data.ref : $attrs.ref;
                                window.g_form._setValue(fieldValue, data.value, data.displayValue);
                                clearDerivedFields(data.value);
                            }
                        }
                        if ($scope.field) {
                            $scope.field.value = data.value;
                            $scope.field.displayValue = data.displayValue;
                        }
                    }
                }
    
                function clearDerivedFields(value) {
                    if (window.DerivedFields) {
                        var df = new DerivedFields($scope.field ? $scope.field.ref : $attrs.ref);
                        df.clearRelated();
                        df.updateRelated(value);
                    }
                }
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/ui/popover/directive.snComplexPopover.js */
    angular.module('sn.common.ui.popover').directive('snComplexPopover', function(getTemplateUrl, $q, $http, $templateCache, $compile, $timeout, $window) {
        "use strict";
        return {
            restrict: 'E',
            replace: true,
            templateUrl: function(elem, attrs) {
                return getTemplateUrl(attrs.buttonTemplate);
            },
            controller: function($scope, $element, $attrs, $q, $document, snCustomEvent, snComplexPopoverService) {
                $scope.type = $attrs.complexPopoverType || "complex_popover";
                if ($scope.closeEvent) {
                    if (typeof $scope.closeEvent === "string") {
                        snCustomEvent.observe($scope.closeEvent, destroyPopover);
                        $scope.$on($scope.closeEvent, destroyPopover);
                    } else if (typeof $scope.closeEvent === "object") {
                        $scope.closeEvent.forEach(function(event) {
                            snCustomEvent.observe(event, destroyPopover);
                            $scope.$on(event, destroyPopover);
                        })
                    }
                }
                $scope.$parent.$on('$destroy', destroyPopover);
                var newScope;
                var open;
                var popover;
                var content;
                var popoverDefaults = {
                    container: 'body',
                    html: true,
                    placement: 'auto',
                    trigger: 'manual',
                    template: '<div class="complex_popover popover" role="tooltip"><div class="arrow"></div><div class="popover-content"></div></div>'
                };
                var popoverConfig = angular.extend(popoverDefaults, $scope.popoverConfig);
                $scope.loading = false;
                $scope.initialized = false;
                $scope.togglePopover = function(event) {
                    if (!$scope.initialized) {
                        showPopover(event);
                    } else {
                        destroyPopover();
                    }
                };
    
                function showPopover(e) {
                    if ($scope.loading)
                        return;
                    $scope.$toggleButton = angular.element(e.target);
                    $scope.loading = true;
                    $scope.$emit('list.toggleLoadingState', true);
                    _getTemplate()
                        .then(_insertTemplate)
                        .then(_createPopover)
                        .then(_bindHtml)
                        .then(function() {
                            $scope.loading = false;
                            $scope.initialized = true;
                            if (!$scope.loadEvent)
                                _openPopover();
                        });
                }
    
                function destroyPopover() {
                    if (!newScope)
                        return;
                    $scope.$toggleButton.on('hidden.bs.popover', function() {
                        open = false;
                        $scope.$toggleButton.data('bs.popover').$element.removeData('bs.popover').off('.popover');
                        $scope.$toggleButton = null;
                        snCustomEvent.fire('hidden.complexpopover.' + $scope.ref);
                    });
                    $scope.$toggleButton.popover('hide');
                    snCustomEvent.fire('hide.complexpopover.' + $scope.ref, $scope.$toggleButton);
                    newScope.$broadcast('$destroy');
                    newScope.$destroy();
                    newScope = null;
                    $scope.initialized = false;
                    angular.element('html').off('click', complexHtmlHandler);
                }
    
                function _getTemplate() {
                    return snComplexPopoverService.getTemplate(getTemplateUrl($attrs.template));
                }
    
                function _createPopover() {
                    $scope.$toggleButton.popover(popoverConfig);
                    return $q.when(true);
                }
    
                function _insertTemplate(response) {
                    newScope = $scope.$new();
                    if ($scope.loadEvent)
                        newScope.$on($scope.loadEvent, _openPopover);
                    content = $compile(response.data)(newScope);
                    popoverConfig.content = content;
                    newScope.open = true;
                    snCustomEvent.fire('inserted.complexpopover.' + $scope.ref, $scope.$toggleButton);
                    return $q.when(true);
                }
    
                function _bindHtml() {
                    angular.element('html').on('click', complexHtmlHandler);
                    return $q.when(true);
                }
    
                function complexHtmlHandler(e) {
                    var parentComplexPopoverScope = angular.element(e.target).parents('.popover-content').children().scope();
                    if (parentComplexPopoverScope && (parentComplexPopoverScope.type = "complex_popover") && $scope.type === "complex_popover")
                        return;
                    if (angular.element(e.target).parents('html').length === 0)
                        return;
                    if ($scope.initialized && !$scope.loading && !$scope.$toggleButton.is(e.target) && content.parents('.popover').has(angular.element(e.target)).length === 0) {
                        e.preventDefault();
                        e.stopPropagation();
                        destroyPopover(e);
                    }
                }
    
                function _openPopover() {
                    if (open)
                        return;
                    open = true;
                    $timeout(function() {
                        $scope.$toggleButton.popover('show');
                        snCustomEvent.fire('show.complexpopover.' + $scope.ref, $scope.$toggleButton);
                        $scope.$toggleButton.on('shown.bs.popover', function() {
                            snCustomEvent.fire('shown.complexpopover.' + $scope.ref, $scope.$toggleButton);
                        });
                    }, 0);
                }
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/ui/popover/service.snComplexPopoverService.js */
    angular.module('sn.common.ui.popover').service('snComplexPopoverService', function($http, $q, $templateCache) {
        "use strict";
        return {
            getTemplate: getTemplate
        };
    
        function getTemplate(template) {
            return $http.get(template, {
                cache: $templateCache
            });
        }
    });;;
    /*! RESOURCE: /scripts/sn/common/ui/directive.snConfirmModal.js */
    angular.module('sn.common.ui').directive('snConfirmModal', function(getTemplateUrl) {
        return {
            templateUrl: getTemplateUrl('sn_confirm_modal.xml'),
            restrict: 'E',
            replace: true,
            transclude: true,
            scope: {
                config: '=?',
                modalName: '@',
                title: '@?',
                message: '@?',
                cancelButton: '@?',
                okButton: '@?',
                alertButton: '@?',
                cancel: '&?',
                ok: '&?',
                alert: '&?'
            },
            link: function(scope, element) {
                element.find('.modal').remove();
            },
            controller: function($scope, $rootScope) {
                $scope.config = $scope.config || {};
    
                function Button(fn, text) {
                    return {
                        fn: fn,
                        text: text
                    }
                }
                var buttons = {
                    'cancelButton': new Button('cancel', 'Cancel'),
                    'okButton': new Button('ok', 'OK'),
                    'alertButton': new Button('alert', 'Close'),
                    getText: function(type) {
                        var button = this[type];
                        if (button && $scope.get(button.fn))
                            return button.text;
                    }
                };
                $scope.get = function(type) {
                    if ($scope.config[type])
                        return $scope.config[type];
                    if (!$scope[type]) {
                        var text = buttons.getText(type);
                        if (text)
                            return $scope.config[type] = text;
                    }
                    return $scope.config[type] = $scope[type];
                };
                if (!$scope.get('modalName'))
                    $scope.config.modalName = 'confirm-modal';
    
                function call(type) {
                    var action = $scope.get(type);
                    if (action) {
                        if (angular.isFunction(action))
                            action();
                        return true;
                    }
                    return !!buttons.getText(type);
                }
                $scope.cancelPressed = close('cancel');
                $scope.okPressed = close('ok');
                $scope.alertPressed = close('alert');
    
                function close(type) {
                    return function() {
                        actionClosed = true;
                        $rootScope.$broadcast('dialog.' + $scope.config.modalName + '.close');
                        call(type);
                    }
                }
                var actionClosed;
                $scope.$on('dialog.' + $scope.get('modalName') + '.opened', function() {
                    actionClosed = false;
                });
                $scope.$on('dialog.' + $scope.get('modalName') + '.closed', function() {
                    if (actionClosed)
                        return;
                    if (call('cancel'))
                        return;
                    if (call('alert'))
                        return;
                    call('ok');
                });
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/ui/directive.snContextMenu.js */
    angular.module('sn.common.ui').directive('contextMenu', function($document, $window, snCustomEvent) {
        var $contextMenu, $ul;
        var scrollHeight = angular.element("body").get(0).scrollHeight;
        var contextMenuItemHeight = 0;
    
        function setContextMenuPosition(event, $ul) {
            if (contextMenuItemHeight === 0)
                contextMenuItemHeight = 24;
            var cmWidth = 150;
            var cmHeight = contextMenuItemHeight * $ul.children().length;
            var startX = event.pageX + cmWidth >= $window.innerWidth ? event.pageX - cmWidth : event.pageX;
            var startY = event.pageY + cmHeight >= $window.innerHeight ? event.pageY - cmHeight : event.pageY;
            $ul.css({
                display: 'block',
                position: 'absolute',
                left: startX,
                top: startY
            });
        }
    
        function renderContextMenuItems($scope, event, options) {
            $ul.empty();
            angular.forEach(options, function(item) {
                var $li = angular.element('<li>');
                if (item === null) {
                    $li.addClass('divider');
                } else {
                    var $a = angular.element('<a>');
                    $a.attr({
                        tabindex: '-1'
                    });
                    $a.text(typeof item[0] == 'string' ? item[0] : item[0].call($scope, $scope));
                    $li.append($a);
                    $li.on('click', function($event) {
                        $event.preventDefault();
                        $scope.$apply(function() {
                            _clearContextMenus(event);
                            item[1].call($scope, $scope);
                        });
                    });
                }
                $ul.append($li);
            });
            setContextMenuPosition(event, $ul);
        }
        var renderContextMenu = function($scope, event, options) {
            angular.element(event.currentTarget).addClass('context');
            $contextMenu = angular.element('<div>', {
                'class': 'dropdown clearfix context-dropdown open'
            });
            $contextMenu.on('click', function(e) {
                if (angular.element(e.target).hasClass('dropdown')) {
                    _clearContextMenus(event);
                }
            });
            $contextMenu.on('contextmenu', function(event) {
                event.preventDefault();
                _clearContextMenus(event);
            });
            $contextMenu.css({
                position: 'absolute',
                top: 0,
                height: scrollHeight,
                left: 0,
                right: 0,
                zIndex: 9999
            });
            $document.find('body').append($contextMenu);
            $ul = angular.element('<ul>', {
                'class': 'dropdown-menu',
                'role': 'menu'
            });
            renderContextMenuItems($scope, event, options);
            $contextMenu.append($ul);
            $contextMenu.data('resizeHandler', function() {
                scrollHeight = angular.element("body").get(0).scrollHeight;
                $contextMenu.css('height', scrollHeight);
            });
            snCustomEvent.observe('partial.page.reload', $contextMenu.data('resizeHandler'));
        };
    
        function _clearContextMenus(event) {
            if (!event) {
                return;
            }
            angular.element(event.currentTarget).removeClass('context');
            var els = angular.element(".context-dropdown");
            angular.forEach(els, function(el) {
                snCustomEvent.un('partial.page.reload', angular.element(el).data('resizeHandler'));
                angular.element(el).remove();
            });
        }
        return function(scope, element, attrs) {
            element.on('contextmenu', function(event) {
                if (event.ctrlKey)
                    return;
                if (angular.element(element).attr('context-type'))
                    return;
                scope.$apply(function() {
                    applyMenu(event);
                    clearWindowSelection();
                });
            });
            element.on('click', function(event) {
                var $el = angular.element(element);
                var $target = angular.element(event.target);
                if (!$el.attr('context-type') && !$target.hasClass('context-menu-click'))
                    return;
                scope.$apply(function() {
                    applyMenu(event);
                    clearWindowSelection();
                });
            });
    
            function clearWindowSelection() {
                if (window.getSelection)
                    if (window.getSelection().empty)
                        window.getSelection().empty();
                    else if (window.getSelection().removeAllRanges)
                    window.getSelection().removeAllRanges();
                else if (document.selection)
                    document.selection.empty();
            }
    
            function applyMenu(event) {
                var tagName = event.target.tagName;
                if (tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'BUTTON') {
                    return;
                }
                var menu = scope.$eval(attrs.contextMenu);
                if (menu instanceof Array) {
                    if (menu.length > 0) {
                        event.stopPropagation();
                        event.preventDefault();
                        scope.$watch(function() {
                            return menu;
                        }, function(newValue, oldValue) {
                            if (newValue !== oldValue) renderContextMenuItems(scope, event, menu);
                        }, true);
                        renderContextMenu(scope, event, menu);
                    }
                } else if (typeof menu !== 'undefined' && typeof menu.then === 'function') {
                    event.stopPropagation();
                    event.preventDefault();
                    menu.then(function(response) {
                        var contextMenu = response;
                        if (contextMenu.length > 0) {
                            scope.$watch(function() {
                                return contextMenu;
                            }, function(newValue, oldValue) {
                                if (newValue !== oldValue)
                                    renderContextMenuItems(scope, event, contextMenu);
                            }, true);
                            renderContextMenu(scope, event, contextMenu);
                        } else {
                            throw '"' + attrs.contextMenu + '" is not an array or promise';
                        }
                    });
                } else {
                    throw '"' + attrs.contextMenu + '" is not an array or promise';
                }
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/ui/directive.snDialog.js */
    angular.module("sn.common.ui").directive("snDialog", function($timeout, $rootScope, $document) {
        "use strict";
        return {
            restrict: "AE",
            transclude: true,
            scope: {
                modal: "=?",
                disableAutoFocus: "=?",
                classCheck: "="
            },
            replace: true,
            template: '<dialog><div ng-click="onClickClose()" class="close-button icon-button icon-cross"></div></dialog>',
            link: function(scope, element, attrs, ctrl, transcludeFn) {
                var transcludeScope = {};
                scope.isOpen = function() {
                    return element[0].open;
                };
                transcludeFn(element.scope().$new(), function(a, b) {
                    element.append(a);
                    transcludeScope = b;
                });
                element.click(function(event) {
                    event.stopPropagation();
                    if (event.offsetX < 0 || event.offsetX > element[0].offsetWidth || event.offsetY < 0 || event.offsetY > element[0].offsetHeight)
                        if (!scope.classCheck)
                            scope.onClickClose();
                        else {
                            var classes = scope.classCheck.split(",");
                            var found = false;
                            for (var i = 0; i < classes.length; i++)
                                if (angular.element(event.srcElement).closest(classes[i]).length > 0)
                                    found = true;
                            if (!found)
                                scope.onClickClose();
                        }
                });
                scope.show = function() {
                    var d = element[0];
                    if (!d.showModal || true) {
                        dialogPolyfill.registerDialog(d);
                        d.setDisableAutoFocus(scope.disableAutoFocus);
                    }
                    if (scope.modal)
                        d.showModal();
                    else
                        d.show();
                    if (!angular.element(d).hasClass('sn-alert')) {
                        $timeout(function() {
                            if (d.dialogPolyfillInfo && d.dialogPolyfillInfo.backdrop) {
                                angular.element(d.dialogPolyfillInfo.backdrop).one('click', function(event) {
                                    if (!scope.classCheck || angular.element(event.srcElement).closest(scope.classCheck).length == 0)
                                        scope.onClickClose();
                                })
                            } else {
                                $document.on('click', function(event) {
                                    if (!scope.classCheck || angular.element(event.srcElement).closest(scope.classCheck).length == 0)
                                        scope.onClickClose();
                                })
                            }
                        });
                    }
                };
                scope.setPosition = function(data) {
                    var contextData = scope.getContextData(data);
                    if (contextData && element && element[0]) {
                        if (contextData.position) {
                            element[0].style.top = contextData.position.top + "px";
                            element[0].style.left = contextData.position.left + "px";
                            element[0].style.margin = "0px";
                        }
                        if (contextData.dimensions) {
                            element[0].style.width = contextData.dimensions.width + "px";
                            element[0].style.height = contextData.dimensions.height + "px";
                        }
                    }
                }
                scope.$on("dialog." + attrs.name + ".move", function(event, data) {
                    scope.setPosition(data);
                })
                scope.$on("dialog." + attrs.name + ".show", function(event, data) {
                    scope.setPosition(data);
                    scope.setKeyEvents(data);
                    if (scope.isOpen() === true)
                        scope.close();
                    else
                        scope.show();
                    angular.element(".sn-dialog-menu").each(function(index, value) {
                        var name = angular.element(this).attr('name');
                        if (name != attrs.name && !angular.element(this).attr('open')) {
                            return true;
                        }
                        if (name != attrs.name && angular.element(this).attr('open')) {
                            $rootScope.$broadcast("dialog." + name + ".close");
                        }
                    });
                })
                scope.onClickClose = function() {
                    if (scope.isOpen())
                        $rootScope.$broadcast("dialog." + attrs.name + ".close");
                }
                scope.close = function() {
                    var d = element[0];
                    d.close();
                    scope.removeListeners();
                }
                scope.ok = function(contextData) {
                    contextData.ok();
                    scope.removeListeners();
                }
                scope.cancel = function(contextData) {
                    contextData.cancel();
                    scope.removeListeners();
                }
                scope.removeListeners = function() {
                    element[0].removeEventListener("ok", scope.handleContextOk, false);
                    element[0].removeEventListener("cancel", scope.handleContextCancel, false);
                }
                scope.setKeyEvents = function(data) {
                    var contextData = scope.getContextData(data);
                    if (contextData && contextData.cancel) {
                        scope.handleContextOk = function() {
                            scope.ok(contextData);
                        }
                        scope.handleContextCancel = function() {
                            scope.cancel(contextData);
                        }
                        element[0].addEventListener("ok", scope.handleContextOk, false);
                        element[0].addEventListener("cancel", scope.handleContextCancel, false);
                    }
                }
                scope.getContextData = function(data) {
                    var context = attrs.context;
                    var contextData = null;
                    if (context && data && context in data) {
                        contextData = data[context];
                        transcludeScope[context] = contextData;
                    }
                    return contextData;
                }
                scope.$on("dialog." + attrs.name + ".close", scope.close);
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/ui/directive.snFlyout.js */
    angular.module('sn.common.ui').directive('snFlyout', function(getTemplateUrl) {
        'use strict';
        return {
            restrict: 'E',
            transclude: true,
            replace: 'true',
            templateUrl: getTemplateUrl('sn_flyout.xml'),
            scope: true,
            link: function($scope, element, attrs) {
                $scope.open = false;
                $scope.more = false;
                $scope.position = attrs.position || 'left';
                $scope.flyoutControl = attrs.control;
                $scope.register = attrs.register;
                var body = angular.element('.flyout-body', element);
                var header = angular.element('.flyout-header', element);
                var tabs = angular.element('.flyout-tabs', element);
                var distance = 0;
                var position = $scope.position;
                var options = {
                    duration: 800,
                    easing: 'easeOutBounce'
                }
                var animation = {};
                if ($scope.flyoutControl) {
                    $('.flyout-handle', element).hide();
                    var controls = angular.element('#' + $scope.flyoutControl);
                    controls.click(function() {
                        angular.element(this).trigger("snFlyout.open");
                    });
                    controls.on('snFlyout.open', function() {
                        $scope.$apply(function() {
                            $scope.open = !$scope.open;
                        });
                    });
                }
                var animate = function() {
                    element.velocity(animation, options);
                }
                var setup = function() {
                    animation[position] = -distance;
                    if ($scope.open)
                        element.css(position, 0);
                    else
                        element.css(position, -distance);
                }
                var calculatePosition = function() {
                    if ($scope.open) {
                        animation[position] = 0;
                    } else {
                        if ($scope.position === 'left' || $scope.position === 'right')
                            animation[position] = -body.outerWidth();
                        else
                            animation[position] = -body.outerHeight();
                    }
                }
                $scope.$watch('open', function(newValue, oldValue) {
                    if (newValue === oldValue)
                        return;
                    calculatePosition();
                    animate();
                });
                $scope.$watch('more', function(newValue, oldValue) {
                    if (newValue === oldValue)
                        return;
                    var moreAnimation = {};
                    if ($scope.more) {
                        element.addClass('fly-double');
                        moreAnimation = {
                            width: body.outerWidth() * 2
                        };
                    } else {
                        element.removeClass('fly-double');
                        moreAnimation = {
                            width: body.outerWidth() / 2
                        };
                    }
                    body.velocity(moreAnimation, options);
                    header.velocity(moreAnimation, options);
                });
                if ($scope.position === 'left' || $scope.position === 'right') {
                    $scope.$watch(element[0].offsetWidth, function() {
                        element.addClass('fly-from-' + $scope.position);
                        distance = body.outerWidth();
                        setup();
                    });
                } else if ($scope.position === 'top' || $scope.position === 'bottom') {
                    $scope.$watch(element[0].offsetWidth, function() {
                        element.addClass('fly-from-' + $scope.position);
                        distance = body.outerHeight() + header.outerHeight();
                        setup();
                    });
                }
                $scope.$on($scope.register + ".bounceTabByIndex", function(event, index) {
                    $scope.bounceTab(index);
                });
                $scope.$on($scope.register + ".bounceTab", function(event, tab) {
                    $scope.bounceTab($scope.tabs.indexOf(tab));
                });
                $scope.$on($scope.register + ".selectTabByIndex", function(event, index) {
                    $scope.selectTab($scope.tabs[index]);
                });
                $scope.$on($scope.register + ".selectTab", function(event, tab) {
                    $scope.selectTab(tab);
                });
            },
            controller: function($scope, $element) {
                $scope.tabs = [];
                var baseColor, highLightColor;
                $scope.selectTab = function(tab) {
                    if ($scope.selectedTab)
                        $scope.selectedTab.selected = false;
                    tab.selected = true;
                    $scope.selectedTab = tab;
                    normalizeTab($scope.tabs.indexOf(tab));
                }
    
                function expandTab(tabElem) {
                    tabElem.queue("tabBounce", function(next) {
                        tabElem.velocity({
                            width: ["2.5rem", "2.125rem"],
                            backgroundColorRed: [highLightColor[0], baseColor[0]],
                            backgroundColorGreen: [highLightColor[1], baseColor[1]],
                            backgroundColorBlue: [highLightColor[2], baseColor[2]]
                        }, {
                            easing: "easeInExpo",
                            duration: 250
                        });
                        next();
                    });
                }
    
                function contractTab(tabElem) {
                    tabElem.queue("tabBounce", function(next) {
                        tabElem.velocity({
                            width: ["2.125rem", "2.5rem"],
                            backgroundColorRed: [baseColor[0], highLightColor[0]],
                            backgroundColorGreen: [baseColor[1], highLightColor[1]],
                            backgroundColorBlue: [baseColor[2], highLightColor[2]]
                        }, {
                            easing: "easeInExpo",
                            duration: 250
                        });
                        next();
                    });
                }
                $scope.bounceTab = function(index) {
                    if (index >= $scope.tabs.length || index < 0)
                        return;
                    var tabScope = $scope.tabs[index];
                    if (!tabScope.selected) {
                        var tabElem = $element.find('.flyout-tab').eq(index);
                        if (!baseColor) {
                            baseColor = tabElem.css('backgroundColor').match(/[0-9]+/g);
                            for (var i = 0; i < baseColor.length; i++)
                                baseColor[i] = parseInt(baseColor[i], 10);
                        }
                        if (!highLightColor)
                            highLightColor = invertColor(baseColor);
                        if (tabScope.highlighted)
                            contractTab(tabElem);
                        for (var i = 0; i < 2; i++) {
                            expandTab(tabElem);
                            contractTab(tabElem);
                        }
                        expandTab(tabElem);
                        tabElem.dequeue("tabBounce");
                        tabScope.highlighted = true;
                    }
                }
                $scope.toggleOpen = function() {
                    $scope.open = !$scope.open;
                }
                this.addTab = function(tab) {
                    $scope.tabs.push(tab);
                    if ($scope.tabs.length === 1)
                        $scope.selectTab(tab)
                }
    
                function normalizeTab(index) {
                    if (index < 0 || index >= $scope.tabs.length || !$scope.tabs[index].highlighted)
                        return;
                    var tabElem = $element.find('.flyout-tab').eq(index);
                    tabElem.velocity({
                        width: ["2.125rem", "2.5rem"]
                    }, {
                        easing: "easeInExpo",
                        duration: 250
                    });
                    tabElem.css('backgroundColor', '');
                    $scope.tabs[index].highlighted = false;
                }
    
                function invertColor(rgb) {
                    if (typeof rgb === "string")
                        var color = rgb.match(/[0-9]+/g);
                    else
                        var color = rgb.slice(0);
                    for (var i = 0; i < color.length; i++)
                        color[i] = 255 - parseInt(color[i], 10);
                    return color;
                }
            }
        }
    }).directive("snFlyoutTab", function() {
        "use strict";
        return {
            restrict: "E",
            require: "^snFlyout",
            replace: true,
            scope: true,
            transclude: true,
            template: "<div ng-show='selected' ng-transclude='' style='height: 100%'></div>",
            link: function(scope, element, attrs, flyoutCtrl) {
                flyoutCtrl.addTab(scope);
            }
        }
    });
    /*! RESOURCE: /scripts/sn/common/ui/directive.snModal.js */
    angular.module("sn.common.ui").directive("snModal", function($timeout, $rootScope) {
        "use strict";
        return {
            restrict: "AE",
            transclude: true,
            scope: {},
            replace: true,
            template: '<div tabindex="-1" aria-hidden="true" class="modal" role="dialog"></div>',
            link: function(scope, element, attrs, ctrl, transcludeFn) {
                var transcludeScope = {};
                transcludeFn(element.scope().$new(), function(a, b) {
                    element.append(a);
                    transcludeScope = b;
                });
                scope.$on("dialog." + attrs.name + ".show", function(event, data) {
                    if (!isOpen())
                        show(data);
                });
                scope.$on("dialog." + attrs.name + ".close", function() {
                    if (isOpen())
                        close();
                });
    
                function eventFn(eventName) {
                    return function(e) {
                        $rootScope.$broadcast("dialog." + attrs.name + "." + eventName, e);
                    }
                }
                var events = {
                    'shown.bs.modal': eventFn("opened"),
                    'hide.bs.modal': eventFn("hide"),
                    'hidden.bs.modal': eventFn("closed")
                };
    
                function show(data) {
                    var context = attrs.context;
                    var contextData = null;
                    if (context && data && context in data) {
                        contextData = data[context];
                        transcludeScope[context] = contextData;
                    }
                    $timeout(function() {
                        angular.element('.sn-popover-basic').each(function() {
                            var $this = angular.element(this);
                            if (angular.element($this.attr('data-target')).is(':visible')) {
                                $this.popover('hide');
                            }
                        });
                    });
                    element.modal('show');
                    for (var event in events)
                        if (events.hasOwnProperty(event))
                            element.on(event, events[event]);
                }
    
                function close() {
                    element.modal('hide');
                    for (var event in events)
                        if (events.hasOwnProperty(event))
                            element.off(event, events[event]);
                }
    
                function isOpen() {
                    return element.hasClass('in');
                }
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/ui/directive.snModalShow.js */
    angular.module('sn.common.ui').directive('snModalShow', function() {
        "use strict";
        return {
            restrict: 'A',
            link: function(scope, element, attrs) {
                element.click(function() {
                    showDialog();
                });
                element.keyup(function(evt) {
                    if (evt.which != 13)
                        return;
                    showDialog();
                });
    
                function showDialog() {
                    scope.$broadcast('dialog.' + attrs.snModalShow + '.show');
                }
                if (window.SingletonKeyboardRegistry) {
                    SingletonKeyboardRegistry.getInstance().bind('ctrl + alt + i', function() {
                        scope.$broadcast('dialog.impersonate.show');
                    }).selector(null, true);
                }
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/ui/directive.snTabs.js */
    angular.module('sn.common.ui').directive('snTabs', function() {
        'use strict';
        return {
            restrict: 'E',
            transclude: true,
            replace: 'true',
            scope: {
                tabData: '='
            },
            link: function($scope, element, attrs) {
                $scope.tabClass = attrs.tabClass;
                $scope.register = attrs.register;
                attrs.$observe('register', function(value) {
                    $scope.register = value;
                    $scope.setupListeners();
                });
                $scope.bounceTab = function() {
                    angular.element()
                }
            },
            controller: 'snTabs'
        }
    }).controller('snTabs', function($scope, $rootScope) {
        $scope.selectedTabIndex = 0;
        $scope.tabData[$scope.selectedTabIndex].selected = true;
        $scope.setupListeners = function() {
            $scope.$on($scope.register + '.selectTabByIndex', function(event, index) {
                $scope.selectTabByIndex(event, index);
            });
        }
        $scope.selectTabByIndex = function(event, index) {
            if (index === $scope.selectedTabIndex)
                return;
            if (event.stopPropagation)
                event.stopPropagation();
            $scope.tabData[$scope.selectedTabIndex].selected = false;
            $scope.tabData[index].selected = true;
            $scope.selectedTabIndex = index;
            $rootScope.$broadcast($scope.register + '.selectTabByIndex', $scope.selectedTabIndex);
        }
    }).directive('snTab', function() {
        'use strict';
        return {
            restrict: 'E',
            transclude: true,
            replace: 'true',
            scope: {
                tabData: '=',
                index: '='
            },
            template: '',
            controller: 'snTab',
            link: function($scope, element, attrs) {
                $scope.register = attrs.register;
                attrs.$observe('register', function(value) {
                    $scope.register = value;
                    $scope.setupListeners();
                });
                $scope.bounceTab = function() {
                    alert('Bounce Tab at Index: ' + $scope.index);
                }
            }
        }
    }).controller('snTab', function($scope) {
        $scope.selectTabByIndex = function(index) {
            $scope.$emit($scope.register + '.selectTabByIndex', index);
        }
        $scope.setupListeners = function() {
            $scope.$on($scope.register + '.showTabActivity', function(event, index, type) {
                $scope.showTabActivity(index, type);
            });
        }
        $scope.showTabActivity = function(index, type) {
            if ($scope.index !== index)
                return;
            switch (type) {
                case 'message':
                    break;
                case 'error':
                    break;
                default:
                    $scope.bounceTab();
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/ui/directive.snTextExpander.js */
    angular.module('sn.common.ui').directive('snTextExpander', function(getTemplateUrl, $timeout) {
        'use strict';
        return {
            restrict: 'E',
            replace: true,
            templateUrl: getTemplateUrl('sn_text_expander.xml'),
            scope: {
                maxHeight: '&',
                value: '='
            },
            link: function compile(scope, element, attrs) {
                var container = angular.element(element).find('.textblock-content-container');
                var content = angular.element(element).find('.textblock-content');
                if (scope.maxHeight() === undefined) {
                    scope.maxHeight = function() {
                        return 100;
                    }
                }
                container.css('overflow-y', 'hidden');
                container.css('max-height', scope.maxHeight() + 'px');
            },
            controller: function($scope, $element) {
                var container = $element.find('.textblock-content-container');
                var content = $element.find('.textblock-content');
                $scope.value = $scope.value || '';
                $scope.toggleExpand = function() {
                    $scope.showMore = !$scope.showMore;
                    if ($scope.showMore) {
                        container.css('max-height', content.height());
                    } else {
                        container.css('max-height', $scope.maxHeight());
                    }
                };
                $timeout(function() {
                    if (content.height() > $scope.maxHeight()) {
                        $scope.showToggle = true;
                        $scope.showMore = false;
                    }
                });
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/ui/directive.snAttachmentPreview.js */
    angular.module('sn.common.ui').directive('snAttachmentPreview', function(getTemplateUrl, snCustomEvent) {
        return {
            restrict: 'E',
            templateUrl: getTemplateUrl('sn_attachment_preview.xml'),
            controller: function($scope) {
                snCustomEvent.observe('sn.attachment.preview', function(evt, attachment) {
                    if (evt.stopPropagation)
                        evt.stopPropagation();
                    if (evt.preventDefault)
                        evt.preventDefault();
                    $scope.image = attachment;
                    $scope.$broadcast('dialog.attachment_preview.show');
                    return false;
                });
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/ui/service.progressDialog.js */
    angular.module('sn.common.ui').factory('progressDialog', ['$rootScope', '$compile', '$timeout', '$http', '$templateCache', 'nowServer', 'i18n', function($rootScope, $compile, $timeout, $http, $templateCache, nowServer, i18n) {
        'use strict';
        i18n.getMessages(['Close']);
        return {
            STATES: ["Pending", "Running", "Succeeded", "Failed", "Cancelled"],
            STATUS_IMAGES: ["images/workflow_skipped.gif", "images/loading_anim2.gifx",
                "images/progress_success.png", "images/progress_failure.png",
                'images/request_cancelled.gif'
            ],
            EXPAND_IMAGE: "images/icons/filter_hide.gif",
            COLLAPSE_IMAGE: "images/icons/filter_reveal.gif",
            BACK_IMAGE: "images/activity_filter_off.gif",
            TIMEOUT_INTERVAL: 750,
            _findChildMessage: function(statusObject) {
                if (!statusObject.children) return null;
                for (var i = 0; i < statusObject.children.length; i++) {
                    var child = statusObject.children[i];
                    if (child.state == '1') {
                        var msg = child.message;
                        var submsg = this._findChildMessage(child);
                        if (submsg == null)
                            return msg;
                        else
                            return null;
                    } else if (child.state == '0') {
                        return null;
                    } else {}
                }
                return null;
            },
            create: function(scope, elemid, title, startCallback, endCallback, closeCallback) {
                var namespace = this;
                var progressItem = scope.$new(true);
                progressItem.id = elemid + "_progressDialog";
                progressItem.overlayVisible = true;
                progressItem.state = 0;
                progressItem.message = '';
                progressItem.percentComplete = 0;
                progressItem.enableChildMessages = false;
                if (!title) title = '';
                progressItem.title = title;
                progressItem.button_close = i18n.getMessage('Close');
                var overlayElement;
                overlayElement = $compile(
                    '<div id="{{id}}" ng-show="overlayVisible" class="modal modal-mask" role="dialog" tabindex="-1">' +
                    '<div class="modal-dialog m_progress_overlay_content">' +
                    '<div class="modal-content">' +
                    '<header class="modal-header">' +
                    '<h4 class="modal-title">{{title}}</h4>' +
                    '</header>' +
                    '<div class="modal-body">' +
                    '<div class="progress" ng-class="{\'progress-danger\': (state == 3)}">' +
                    '<div class="progress-bar" ng-class="{\'progress-bar-danger\': (state == 3)}" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="{{percentComplete}}" ng-style="{width: percentComplete + \'%\'}">' +
                    '</div>' +
                    '</div>' +
                    '<div>{{message}}<span style="float: right;" ng-show="state==1 || state == 2">{{percentComplete}}%</span></div>' +
                    '</div>' +
                    '<footer class="modal-footer">' +
                    '<button class="btn btn-default sn-button sn-button-normal" ng-click="close()" ng-show="state > 1">{{button_close}}</button>' +
                    '</footer>' +
                    '</div>' +
                    '</div>' +
                    '</div>')(progressItem);
                $("body")[0].appendChild(overlayElement[0]);
                progressItem.setEnableChildMessages = function(enableChildren) {
                    progressItem.enableChildMessages = enableChildren;
                }
                progressItem.start = function(src, dataArray) {
                    $http.post(src, dataArray).success(function(response) {
                            progressItem.trackerId = response;
                            try {
                                if (startCallback) startCallback(response);
                            } catch (e) {}
                            $timeout(progressItem.checkProgress.bind(progressItem));
                        })
                        .error(function(response, status, headers, config) {
                            progressItem.state = '3';
                            if (endCallback) endCallback(response);
                        });
                };
                progressItem.checkProgress = function() {
                    var src = nowServer.getURL('progress_status', {
                        sysparm_execution_id: this.trackerId
                    });
                    $http.post(src).success(function(response) {
                            if ($.isEmptyObject(response)) {
                                progressItem.state = '3';
                                if (endCallback) endCallback(response);
                                return;
                            }
                            progressItem.update(response);
                            if (response.status == 'error' || response.state == '') {
                                progressItem.state = '3';
                                if (response.message)
                                    progressItem.message = response.message;
                                else
                                    progressItem.message = response;
                                if (endCallback) endCallback(response);
                                return;
                            }
                            if (response.state == '0' || response.state == '1') {
                                $timeout(progressItem.checkProgress.bind(progressItem), namespace.TIMEOUT_INTERVAL);
                            } else {
                                if (endCallback) endCallback(response);
                            }
                        })
                        .error(function(response, status, headers, config) {
                            progressItem.state = '3';
                            progressItem.message = response;
                            if (endCallback) endCallback(response);
                        });
                };
                progressItem.update = function(statusObject) {
                    var msg = statusObject.message;
                    if (progressItem.enableChildMessages) {
                        var childMsg = namespace._findChildMessage(statusObject);
                        if (childMsg != null)
                            msg = childMsg;
                    }
                    this.message = msg;
                    this.state = statusObject.state;
                    this.percentComplete = statusObject.percent_complete;
                };
                progressItem.close = function(ev) {
                    try {
                        if (closeCallback) closeCallback();
                    } catch (e) {}
                    $("body")[0].removeChild($("#" + this.id)[0]);
                    delete namespace.progressItem;
                };
                return progressItem;
            }
        }
    }]);;
    /*! RESOURCE: /scripts/sn/common/ui/factory.paneManager.js */
    angular.module("sn.common.ui").factory("paneManager", ['$timeout', 'userPreferences', 'snCustomEvent', function($timeout, userPreferences, snCustomEvent) {
        "use strict";
        var paneIndex = {};
    
        function registerPane(paneName) {
            if (!paneName in paneIndex) {
                paneIndex[paneName] = false;
            }
            userPreferences.getPreference(paneName + '.opened').then(function(value) {
                var isOpen = value !== 'false';
                if (isOpen) {
                    togglePane(paneName);
                }
            });
        }
    
        function togglePane(paneName) {
            for (var currentPane in paneIndex) {
                if (paneName != currentPane && paneIndex[currentPane]) {
                    CustomEvent.fireTop(currentPane + '.toggle');
                    saveState(currentPane, false);
                }
            }
            snCustomEvent.fireTop(paneName + '.toggle');
            saveState(paneName, !paneIndex[paneName]);
        };
    
        function saveState(paneName, state) {
            paneIndex[paneName] = state;
            userPreferences.setPreference(paneName + '.opened', state);
        }
        return {
            registerPane: registerPane,
            togglePane: togglePane
        };
    }]);;;
    /*! RESOURCE: /scripts/sn/common/stream/js_includes_stream.js */
    /*! RESOURCE: /scripts/thirdparty/ment.io/mentio.js */
    (function() {
        'use strict';
        angular.module('mentio', [])
            .directive('mentio', ['mentioUtil', '$document', '$compile', '$log', '$timeout',
                function(mentioUtil, $document, $compile, $log, $timeout) {
                    return {
                        restrict: 'A',
                        scope: {
                            macros: '=mentioMacros',
                            search: '&mentioSearch',
                            select: '&mentioSelect',
                            items: '=mentioItems',
                            typedTerm: '=mentioTypedTerm',
                            altId: '=mentioId',
                            iframeElement: '=mentioIframeElement',
                            requireLeadingSpace: '=mentioRequireLeadingSpace',
                            suppressTrailingSpace: '=mentioSuppressTrailingSpace',
                            selectNotFound: '=mentioSelectNotFound',
                            trimTerm: '=mentioTrimTerm',
                            ngModel: '='
                        },
                        controller: ["$scope", "$timeout", "$attrs", function($scope, $timeout, $attrs) {
                            $scope.query = function(triggerChar, triggerText) {
                                var remoteScope = $scope.triggerCharMap[triggerChar];
                                if ($scope.trimTerm === undefined || $scope.trimTerm) {
                                    triggerText = triggerText.trim();
                                }
                                remoteScope.showMenu();
                                remoteScope.search({
                                    term: triggerText
                                });
                                remoteScope.typedTerm = triggerText;
                            };
                            $scope.defaultSearch = function(locals) {
                                var results = [];
                                angular.forEach($scope.items, function(item) {
                                    if (item.label.toUpperCase().indexOf(locals.term.toUpperCase()) >= 0) {
                                        results.push(item);
                                    }
                                });
                                $scope.localItems = results;
                            };
                            $scope.bridgeSearch = function(termString) {
                                var searchFn = $attrs.mentioSearch ? $scope.search : $scope.defaultSearch;
                                searchFn({
                                    term: termString
                                });
                            };
                            $scope.defaultSelect = function(locals) {
                                return $scope.defaultTriggerChar + locals.item.label;
                            };
                            $scope.bridgeSelect = function(itemVar) {
                                var selectFn = $attrs.mentioSelect ? $scope.select : $scope.defaultSelect;
                                return selectFn({
                                    item: itemVar
                                });
                            };
                            $scope.setTriggerText = function(text) {
                                if ($scope.syncTriggerText) {
                                    $scope.typedTerm = ($scope.trimTerm === undefined || $scope.trimTerm) ? text.trim() : text;
                                }
                            };
                            $scope.context = function() {
                                if ($scope.iframeElement) {
                                    return {
                                        iframe: $scope.iframeElement
                                    };
                                }
                            };
                            $scope.replaceText = function(text, hasTrailingSpace) {
                                $scope.hideAll();
                                mentioUtil.replaceTriggerText($scope.context(), $scope.targetElement, $scope.targetElementPath,
                                    $scope.targetElementSelectedOffset, $scope.triggerCharSet, text, $scope.requireLeadingSpace,
                                    hasTrailingSpace, $scope.suppressTrailingSpace);
                                if (!hasTrailingSpace) {
                                    $scope.setTriggerText('');
                                    angular.element($scope.targetElement).triggerHandler('change');
                                    if ($scope.isContentEditable()) {
                                        $scope.contentEditableMenuPasted = true;
                                        var timer = $timeout(function() {
                                            $scope.contentEditableMenuPasted = false;
                                        }, 200);
                                        $scope.$on('$destroy', function() {
                                            $timeout.cancel(timer);
                                        });
                                    }
                                }
                            };
                            $scope.hideAll = function() {
                                for (var key in $scope.triggerCharMap) {
                                    if ($scope.triggerCharMap.hasOwnProperty(key)) {
                                        $scope.triggerCharMap[key].hideMenu();
                                    }
                                }
                            };
                            $scope.getActiveMenuScope = function() {
                                for (var key in $scope.triggerCharMap) {
                                    if ($scope.triggerCharMap.hasOwnProperty(key)) {
                                        if ($scope.triggerCharMap[key].visible) {
                                            return $scope.triggerCharMap[key];
                                        }
                                    }
                                }
                                return null;
                            };
                            $scope.selectActive = function() {
                                for (var key in $scope.triggerCharMap) {
                                    if ($scope.triggerCharMap.hasOwnProperty(key)) {
                                        if ($scope.triggerCharMap[key].visible) {
                                            $scope.triggerCharMap[key].selectActive();
                                        }
                                    }
                                }
                            };
                            $scope.isActive = function() {
                                for (var key in $scope.triggerCharMap) {
                                    if ($scope.triggerCharMap.hasOwnProperty(key)) {
                                        if ($scope.triggerCharMap[key].visible) {
                                            return true;
                                        }
                                    }
                                }
                                return false;
                            };
                            $scope.isContentEditable = function() {
                                return ($scope.targetElement.nodeName !== 'INPUT' && $scope.targetElement.nodeName !== 'TEXTAREA');
                            };
                            $scope.replaceMacro = function(macro, hasTrailingSpace) {
                                if (!hasTrailingSpace) {
                                    $scope.replacingMacro = true;
                                    $scope.timer = $timeout(function() {
                                        mentioUtil.replaceMacroText($scope.context(), $scope.targetElement,
                                            $scope.targetElementPath, $scope.targetElementSelectedOffset,
                                            $scope.macros, $scope.macros[macro]);
                                        angular.element($scope.targetElement).triggerHandler('change');
                                        $scope.replacingMacro = false;
                                    }, 300);
                                    $scope.$on('$destroy', function() {
                                        $timeout.cancel($scope.timer);
                                    });
                                } else {
                                    mentioUtil.replaceMacroText($scope.context(), $scope.targetElement, $scope.targetElementPath,
                                        $scope.targetElementSelectedOffset, $scope.macros, $scope.macros[macro]);
                                }
                            };
                            $scope.addMenu = function(menuScope) {
                                if (menuScope.parentScope && $scope.triggerCharMap.hasOwnProperty(menuScope.triggerChar)) {
                                    return;
                                }
                                $scope.triggerCharMap[menuScope.triggerChar] = menuScope;
                                if ($scope.triggerCharSet === undefined) {
                                    $scope.triggerCharSet = [];
                                }
                                $scope.triggerCharSet.push(menuScope.triggerChar);
                                menuScope.setParent($scope);
                            };
                            $scope.$on(
                                'menuCreated',
                                function(event, data) {
                                    if (
                                        $attrs.id !== undefined ||
                                        $attrs.mentioId !== undefined
                                    ) {
                                        if (
                                            $attrs.id === data.targetElement ||
                                            (
                                                $attrs.mentioId !== undefined &&
                                                $scope.altId === data.targetElement
                                            )
                                        ) {
                                            $scope.addMenu(data.scope);
                                        }
                                    }
                                }
                            );
                            $document.on(
                                'click',
                                function() {
                                    if ($scope.isActive()) {
                                        $scope.$apply(function() {
                                            $scope.hideAll();
                                        });
                                    }
                                }
                            );
                            $document.on(
                                'keydown keypress paste',
                                function(event) {
                                    var activeMenuScope = $scope.getActiveMenuScope();
                                    if (activeMenuScope) {
                                        if (event.which === 9 || event.which === 13) {
                                            event.preventDefault();
                                            activeMenuScope.selectActive();
                                        }
                                        if (event.which === 27) {
                                            event.preventDefault();
                                            activeMenuScope.$apply(function() {
                                                activeMenuScope.hideMenu();
                                            });
                                        }
                                        if (event.which === 40) {
                                            event.preventDefault();
                                            activeMenuScope.$apply(function() {
                                                activeMenuScope.activateNextItem();
                                            });
                                            activeMenuScope.adjustScroll(1);
                                        }
                                        if (event.which === 38) {
                                            event.preventDefault();
                                            activeMenuScope.$apply(function() {
                                                activeMenuScope.activatePreviousItem();
                                            });
                                            activeMenuScope.adjustScroll(-1);
                                        }
                                        if (event.which === 37 || event.which === 39) {
                                            event.preventDefault();
                                        }
                                    }
                                }
                            );
                        }],
                        link: function(scope, element, attrs) {
                            scope.triggerCharMap = {};
                            scope.targetElement = element;
                            attrs.$set('autocomplete', 'off');
                            if (attrs.mentioItems) {
                                scope.localItems = [];
                                scope.parentScope = scope;
                                var itemsRef = attrs.mentioSearch ? ' mentio-items="items"' : ' mentio-items="localItems"';
                                scope.defaultTriggerChar = attrs.mentioTriggerChar ? scope.$eval(attrs.mentioTriggerChar) : '@';
                                var html = '<mentio-menu' +
                                    ' mentio-search="bridgeSearch(term)"' +
                                    ' mentio-select="bridgeSelect(item)"' +
                                    itemsRef;
                                if (attrs.mentioTemplateUrl) {
                                    html = html + ' mentio-template-url="' + attrs.mentioTemplateUrl + '"';
                                }
                                html = html + ' mentio-trigger-char="\'' + scope.defaultTriggerChar + '\'"' +
                                    ' mentio-parent-scope="parentScope"' +
                                    '/>';
                                var linkFn = $compile(html);
                                var el = linkFn(scope);
                                element.parent().append(el);
                                scope.$on('$destroy', function() {
                                    el.remove();
                                });
                            }
                            if (attrs.mentioTypedTerm) {
                                scope.syncTriggerText = true;
                            }
    
                            function keyHandler(event) {
                                function stopEvent(event) {
                                    event.preventDefault();
                                    event.stopPropagation();
                                    event.stopImmediatePropagation();
                                }
                                var activeMenuScope = scope.getActiveMenuScope();
                                if (activeMenuScope) {
                                    if (event.which === 9 || event.which === 13) {
                                        stopEvent(event);
                                        activeMenuScope.selectActive();
                                        return false;
                                    }
                                    if (event.which === 27) {
                                        stopEvent(event);
                                        activeMenuScope.$apply(function() {
                                            activeMenuScope.hideMenu();
                                        });
                                        return false;
                                    }
                                    if (event.which === 40) {
                                        stopEvent(event);
                                        activeMenuScope.$apply(function() {
                                            activeMenuScope.activateNextItem();
                                        });
                                        activeMenuScope.adjustScroll(1);
                                        return false;
                                    }
                                    if (event.which === 38) {
                                        stopEvent(event);
                                        activeMenuScope.$apply(function() {
                                            activeMenuScope.activatePreviousItem();
                                        });
                                        activeMenuScope.adjustScroll(-1);
                                        return false;
                                    }
                                    if (event.which === 37 || event.which === 39) {
                                        stopEvent(event);
                                        return false;
                                    }
                                }
                            }
                            scope.$watch(
                                'iframeElement',
                                function(newValue) {
                                    if (newValue) {
                                        var iframeDocument = newValue.contentWindow.document;
                                        iframeDocument.addEventListener('click',
                                            function() {
                                                if (scope.isActive()) {
                                                    scope.$apply(function() {
                                                        scope.hideAll();
                                                    });
                                                }
                                            }
                                        );
                                        iframeDocument.addEventListener('keydown', keyHandler, true);
                                        scope.$on('$destroy', function() {
                                            iframeDocument.removeEventListener('keydown', keyHandler);
                                        });
                                    }
                                }
                            );
                            scope.$watch(
                                'ngModel',
                                function(newValue) {
                                    if ((!newValue || newValue === '') && !scope.isActive()) {
                                        return;
                                    }
                                    if (scope.triggerCharSet === undefined) {
                                        $log.warn('Error, no mentio-items attribute was provided, ' +
                                            'and no separate mentio-menus were specified.  Nothing to do.');
                                        return;
                                    }
                                    if (scope.contentEditableMenuPasted) {
                                        scope.contentEditableMenuPasted = false;
                                        return;
                                    }
                                    if (scope.replacingMacro) {
                                        $timeout.cancel(scope.timer);
                                        scope.replacingMacro = false;
                                    }
                                    var isActive = scope.isActive();
                                    var isContentEditable = scope.isContentEditable();
                                    var mentionInfo = mentioUtil.getTriggerInfo(scope.context(), scope.triggerCharSet,
                                        scope.requireLeadingSpace, isActive);
                                    if (mentionInfo !== undefined &&
                                        (!isActive ||
                                            (isActive &&
                                                (
                                                    (isContentEditable && mentionInfo.mentionTriggerChar ===
                                                        scope.currentMentionTriggerChar) ||
                                                    (!isContentEditable && mentionInfo.mentionPosition ===
                                                        scope.currentMentionPosition)
                                                )
                                            )
                                        )
                                    ) {
                                        if (mentionInfo.mentionSelectedElement) {
                                            scope.targetElement = mentionInfo.mentionSelectedElement;
                                            scope.targetElementPath = mentionInfo.mentionSelectedPath;
                                            scope.targetElementSelectedOffset = mentionInfo.mentionSelectedOffset;
                                        }
                                        scope.setTriggerText(mentionInfo.mentionText);
                                        scope.currentMentionPosition = mentionInfo.mentionPosition;
                                        scope.currentMentionTriggerChar = mentionInfo.mentionTriggerChar;
                                        scope.query(mentionInfo.mentionTriggerChar, mentionInfo.mentionText);
                                    } else {
                                        var currentTypedTerm = scope.typedTerm;
                                        scope.setTriggerText('');
                                        scope.hideAll();
                                        var macroMatchInfo = mentioUtil.getMacroMatch(scope.context(), scope.macros);
                                        if (macroMatchInfo !== undefined) {
                                            scope.targetElement = macroMatchInfo.macroSelectedElement;
                                            scope.targetElementPath = macroMatchInfo.macroSelectedPath;
                                            scope.targetElementSelectedOffset = macroMatchInfo.macroSelectedOffset;
                                            scope.replaceMacro(macroMatchInfo.macroText, macroMatchInfo.macroHasTrailingSpace);
                                        } else if (scope.selectNotFound && currentTypedTerm && currentTypedTerm !== '') {
                                            var lastScope = scope.triggerCharMap[scope.currentMentionTriggerChar];
                                            if (lastScope) {
                                                var text = lastScope.select({
                                                    item: {
                                                        label: currentTypedTerm
                                                    }
                                                });
                                                if (typeof text.then === 'function') {
                                                    text.then(scope.replaceText);
                                                } else {
                                                    scope.replaceText(text, true);
                                                }
                                            }
                                        }
                                    }
                                }
                            );
                        }
                    };
                }
            ])
            .directive('mentioMenu', ['mentioUtil', '$rootScope', '$log', '$window', '$document', '$timeout',
                function(mentioUtil, $rootScope, $log, $window, $document, $timeout) {
                    return {
                        restrict: 'E',
                        scope: {
                            search: '&mentioSearch',
                            select: '&mentioSelect',
                            items: '=mentioItems',
                            triggerChar: '=mentioTriggerChar',
                            forElem: '=mentioFor',
                            parentScope: '=mentioParentScope'
                        },
                        templateUrl: function(tElement, tAttrs) {
                            return tAttrs.mentioTemplateUrl !== undefined ? tAttrs.mentioTemplateUrl : 'mentio-menu.tpl.html';
                        },
                        controller: ["$scope", function($scope) {
                            $scope.visible = false;
                            this.activate = $scope.activate = function(item) {
                                $scope.activeItem = item;
                            };
                            this.isActive = $scope.isActive = function(item) {
                                return $scope.activeItem === item;
                            };
                            this.selectItem = $scope.selectItem = function(item) {
                                if (item.termLengthIsZero) {
                                    item.name = $scope.triggerChar + $scope.typedTerm
                                }
                                var text = $scope.select({
                                    item: item
                                });
                                if (typeof text.then === 'function') {
                                    text.then($scope.parentMentio.replaceText);
                                } else {
                                    $scope.parentMentio.replaceText(text);
                                }
                            };
                            $scope.activateNextItem = function() {
                                var index = $scope.items.indexOf($scope.activeItem);
                                this.activate($scope.items[(index + 1) % $scope.items.length]);
                            };
                            $scope.activatePreviousItem = function() {
                                var index = $scope.items.indexOf($scope.activeItem);
                                this.activate($scope.items[index === 0 ? $scope.items.length - 1 : index - 1]);
                            };
                            $scope.isFirstItemActive = function() {
                                var index = $scope.items.indexOf($scope.activeItem);
                                return index === 0;
                            };
                            $scope.isLastItemActive = function() {
                                var index = $scope.items.indexOf($scope.activeItem);
                                return index === ($scope.items.length - 1);
                            };
                            $scope.selectActive = function() {
                                $scope.selectItem($scope.activeItem);
                            };
                            $scope.isVisible = function() {
                                return $scope.visible;
                            };
                            $scope.showMenu = function() {
                                if (!$scope.visible) {
                                    $scope.menuElement.css("visibility", "visible");
                                    $scope.requestVisiblePendingSearch = true;
                                }
                            };
                            $scope.setParent = function(scope) {
                                $scope.parentMentio = scope;
                                $scope.targetElement = scope.targetElement;
                            };
                        }],
                        link: function(scope, element) {
                            element[0].parentNode.removeChild(element[0]);
                            $document[0].body.appendChild(element[0]);
                            scope.menuElement = element;
                            scope.menuElement.css("visibility", "hidden");
                            if (scope.parentScope) {
                                scope.parentScope.addMenu(scope);
                            } else {
                                if (!scope.forElem) {
                                    $log.error('mentio-menu requires a target element in tbe mentio-for attribute');
                                    return;
                                }
                                if (!scope.triggerChar) {
                                    $log.error('mentio-menu requires a trigger char');
                                    return;
                                }
                                $rootScope.$broadcast('menuCreated', {
                                    targetElement: scope.forElem,
                                    scope: scope
                                });
                            }
                            angular.element($window).bind(
                                'resize',
                                function() {
                                    if (scope.isVisible()) {
                                        var triggerCharSet = [];
                                        triggerCharSet.push(scope.triggerChar);
                                        mentioUtil.popUnderMention(scope.parentMentio.context(),
                                            triggerCharSet, element, scope.requireLeadingSpace);
                                    }
                                }
                            );
                            scope.$watch('items', function(items) {
                                if (items && items.length > 0) {
                                    scope.activate(items[0]);
                                    if (!scope.visible && scope.requestVisiblePendingSearch) {
                                        scope.visible = true;
                                        scope.requestVisiblePendingSearch = false;
                                    }
                                    $timeout(function() {
                                        var menu = element.find(".dropdown-menu");
                                        if (menu.length > 0 && menu.offset().top < 0)
                                            menu.addClass("reverse");
                                    }, 0, false);
                                } else {
                                    scope.activate({
                                        termLengthIsZero: true
                                    });
                                }
                            });
                            scope.$watch('isVisible()', function(visible) {
                                if (visible) {
                                    var triggerCharSet = [];
                                    triggerCharSet.push(scope.triggerChar);
                                    mentioUtil.popUnderMention(scope.parentMentio.context(),
                                        triggerCharSet, element, scope.requireLeadingSpace);
                                } else {
                                    element.find(".dropdown-menu").removeClass("reverse");
                                }
                            });
                            scope.parentMentio.$on('$destroy', function() {
                                element.remove();
                            });
                            scope.hideMenu = function() {
                                scope.visible = false;
                                element.css('display', 'none');
                            };
                            scope.adjustScroll = function(direction) {
                                var menuEl = element[0];
                                var menuItemsList = menuEl.querySelector('ul');
                                var menuItem = menuEl.querySelector('[mentio-menu-item].active');
                                if (scope.isFirstItemActive()) {
                                    return menuItemsList.scrollTop = 0;
                                } else if (scope.isLastItemActive()) {
                                    return menuItemsList.scrollTop = menuItemsList.scrollHeight;
                                }
                                if (direction === 1) {
                                    menuItemsList.scrollTop += menuItem.offsetHeight;
                                } else {
                                    menuItemsList.scrollTop -= menuItem.offsetHeight;
                                }
                            };
                        }
                    };
                }
            ])
            .directive('mentioMenuItem', function() {
                return {
                    restrict: 'A',
                    scope: {
                        item: '=mentioMenuItem'
                    },
                    require: '^mentioMenu',
                    link: function(scope, element, attrs, controller) {
                        scope.$watch(function() {
                            return controller.isActive(scope.item);
                        }, function(active) {
                            if (active) {
                                element.addClass('active');
                            } else {
                                element.removeClass('active');
                            }
                        });
                        element.bind('mouseenter', function() {
                            scope.$apply(function() {
                                controller.activate(scope.item);
                            });
                        });
                        element.bind('click', function() {
                            controller.selectItem(scope.item);
                            return false;
                        });
                    }
                };
            })
            .filter('unsafe', ["$sce", function($sce) {
                return function(val) {
                    return $sce.trustAsHtml(val);
                };
            }])
            .filter('mentioHighlight', function() {
                function escapeRegexp(queryToEscape) {
                    return queryToEscape.replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
                }
                return function(matchItem, query, hightlightClass) {
                    if (query) {
                        var replaceText = hightlightClass ?
                            '<span class="' + hightlightClass + '">$&</span>' :
                            '<strong>$&</strong>';
                        return ('' + matchItem).replace(new RegExp(escapeRegexp(query), 'gi'), replaceText);
                    } else {
                        return matchItem;
                    }
                };
            });
        'use strict';
        angular.module('mentio')
            .factory('mentioUtil', ["$window", "$location", "$anchorScroll", "$timeout", function($window, $location, $anchorScroll, $timeout) {
                function popUnderMention(ctx, triggerCharSet, selectionEl, requireLeadingSpace) {
                    var coordinates;
                    var mentionInfo = getTriggerInfo(ctx, triggerCharSet, requireLeadingSpace, false);
                    if (mentionInfo !== undefined) {
                        if (selectedElementIsTextAreaOrInput(ctx)) {
                            coordinates = getTextAreaOrInputUnderlinePosition(ctx, getDocument(ctx).activeElement,
                                mentionInfo.mentionPosition);
                        } else {
                            coordinates = getContentEditableCaretPosition(ctx, mentionInfo.mentionPosition);
                        }
                        selectionEl.css({
                            top: coordinates.top + 'px',
                            left: coordinates.left + 'px',
                            position: 'absolute',
                            zIndex: 5000,
                            display: 'block'
                        });
                        $timeout(function() {
                            scrollIntoView(ctx, selectionEl);
                        }, 0);
                    } else {
                        selectionEl.css({
                            display: 'none'
                        });
                    }
                }
    
                function scrollIntoView(ctx, elem) {
                    var reasonableBuffer = 20;
                    var maxScrollDisplacement = 100;
                    var clientRect;
                    var e = elem[0];
                    while (clientRect === undefined || clientRect.height === 0) {
                        clientRect = e.getBoundingClientRect();
                        if (clientRect.height === 0) {
                            e = e.childNodes[0];
                            if (e === undefined || !e.getBoundingClientRect) {
                                return;
                            }
                        }
                    }
                    var elemTop = clientRect.top;
                    var elemBottom = elemTop + clientRect.height;
                    if (elemTop < 0) {
                        $window.scrollTo(0, $window.pageYOffset + clientRect.top - reasonableBuffer);
                    } else if (elemBottom > $window.innerHeight) {
                        var maxY = $window.pageYOffset + clientRect.top - reasonableBuffer;
                        if (maxY - $window.pageYOffset > maxScrollDisplacement) {
                            maxY = $window.pageYOffset + maxScrollDisplacement;
                        }
                        var targetY = $window.pageYOffset - ($window.innerHeight - elemBottom);
                        if (targetY > maxY) {
                            targetY = maxY;
                        }
                        $window.scrollTo(0, targetY);
                    }
                }
    
                function selectedElementIsTextAreaOrInput(ctx) {
                    var element = getDocument(ctx).activeElement;
                    if (element !== null) {
                        var nodeName = element.nodeName;
                        var type = element.getAttribute('type');
                        return (nodeName === 'INPUT' && type === 'text') || nodeName === 'TEXTAREA';
                    }
                    return false;
                }
    
                function selectElement(ctx, targetElement, path, offset) {
                    var range;
                    var elem = targetElement;
                    if (path) {
                        for (var i = 0; i < path.length; i++) {
                            elem = elem.childNodes[path[i]];
                            if (elem === undefined) {
                                return;
                            }
                            while (elem.length < offset) {
                                offset -= elem.length;
                                elem = elem.nextSibling;
                            }
                            if (elem.childNodes.length === 0 && !elem.length) {
                                elem = elem.previousSibling;
                            }
                        }
                    }
                    var sel = getWindowSelection(ctx);
                    range = getDocument(ctx).createRange();
                    range.setStart(elem, offset);
                    range.setEnd(elem, offset);
                    range.collapse(true);
                    try {
                        sel.removeAllRanges();
                    } catch (error) {}
                    sel.addRange(range);
                    targetElement.focus();
                }
    
                function pasteHtml(ctx, html, startPos, endPos) {
                    var range, sel;
                    sel = getWindowSelection(ctx);
                    range = getDocument(ctx).createRange();
                    range.setStart(sel.anchorNode, startPos);
                    range.setEnd(sel.anchorNode, endPos);
                    range.deleteContents();
                    var el = getDocument(ctx).createElement('div');
                    el.innerHTML = html;
                    var frag = getDocument(ctx).createDocumentFragment(),
                        node, lastNode;
                    while ((node = el.firstChild)) {
                        lastNode = frag.appendChild(node);
                    }
                    range.insertNode(frag);
                    if (lastNode) {
                        range = range.cloneRange();
                        range.setStartAfter(lastNode);
                        range.collapse(true);
                        sel.removeAllRanges();
                        sel.addRange(range);
                    }
                }
    
                function resetSelection(ctx, targetElement, path, offset) {
                    var nodeName = targetElement.nodeName;
                    if (nodeName === 'INPUT' || nodeName === 'TEXTAREA') {
                        if (targetElement !== getDocument(ctx).activeElement) {
                            targetElement.focus();
                        }
                    } else {
                        selectElement(ctx, targetElement, path, offset);
                    }
                }
    
                function replaceMacroText(ctx, targetElement, path, offset, macros, text) {
                    resetSelection(ctx, targetElement, path, offset);
                    var macroMatchInfo = getMacroMatch(ctx, macros);
                    if (macroMatchInfo.macroHasTrailingSpace) {
                        macroMatchInfo.macroText = macroMatchInfo.macroText + '\xA0';
                        text = text + '\xA0';
                    }
                    if (macroMatchInfo !== undefined) {
                        var element = getDocument(ctx).activeElement;
                        if (selectedElementIsTextAreaOrInput(ctx)) {
                            var startPos = macroMatchInfo.macroPosition;
                            var endPos = macroMatchInfo.macroPosition + macroMatchInfo.macroText.length;
                            element.value = element.value.substring(0, startPos) + text +
                                element.value.substring(endPos, element.value.length);
                            element.selectionStart = startPos + text.length;
                            element.selectionEnd = startPos + text.length;
                        } else {
                            pasteHtml(ctx, text, macroMatchInfo.macroPosition,
                                macroMatchInfo.macroPosition + macroMatchInfo.macroText.length);
                        }
                    }
                }
    
                function replaceTriggerText(ctx, targetElement, path, offset, triggerCharSet,
                    text, requireLeadingSpace, hasTrailingSpace, suppressTrailingSpace) {
                    resetSelection(ctx, targetElement, path, offset);
                    var mentionInfo = getTriggerInfo(ctx, triggerCharSet, requireLeadingSpace, true, hasTrailingSpace);
                    if (mentionInfo !== undefined) {
                        if (selectedElementIsTextAreaOrInput()) {
                            var myField = getDocument(ctx).activeElement;
                            if (!suppressTrailingSpace) {
                                text = text + ' ';
                            }
                            var startPos = mentionInfo.mentionPosition;
                            var endPos = mentionInfo.mentionPosition + mentionInfo.mentionText.length + 1;
                            myField.value = myField.value.substring(0, startPos) + text +
                                myField.value.substring(endPos, myField.value.length);
                            myField.selectionStart = startPos + text.length;
                            myField.selectionEnd = startPos + text.length;
                        } else {
                            if (!suppressTrailingSpace) {
                                text = text + '\xA0';
                            }
                            pasteHtml(ctx, text, mentionInfo.mentionPosition,
                                mentionInfo.mentionPosition + mentionInfo.mentionText.length + 1);
                        }
                    }
                }
    
                function getNodePositionInParent(ctx, elem) {
                    if (elem.parentNode === null) {
                        return 0;
                    }
                    for (var i = 0; i < elem.parentNode.childNodes.length; i++) {
                        var node = elem.parentNode.childNodes[i];
                        if (node === elem) {
                            return i;
                        }
                    }
                }
    
                function getMacroMatch(ctx, macros) {
                    var selected, path = [],
                        offset;
                    if (selectedElementIsTextAreaOrInput(ctx)) {
                        selected = getDocument(ctx).activeElement;
                    } else {
                        var selectionInfo = getContentEditableSelectedPath(ctx);
                        if (selectionInfo) {
                            selected = selectionInfo.selected;
                            path = selectionInfo.path;
                            offset = selectionInfo.offset;
                        }
                    }
                    var effectiveRange = getTextPrecedingCurrentSelection(ctx);
                    if (effectiveRange !== undefined && effectiveRange !== null) {
                        var matchInfo;
                        var hasTrailingSpace = false;
                        if (effectiveRange.length > 0 &&
                            (effectiveRange.charAt(effectiveRange.length - 1) === '\xA0' ||
                                effectiveRange.charAt(effectiveRange.length - 1) === ' ')) {
                            hasTrailingSpace = true;
                            effectiveRange = effectiveRange.substring(0, effectiveRange.length - 1);
                        }
                        angular.forEach(macros, function(macro, c) {
                            var idx = effectiveRange.toUpperCase().lastIndexOf(c.toUpperCase());
                            if (idx >= 0 && c.length + idx === effectiveRange.length) {
                                var prevCharPos = idx - 1;
                                if (idx === 0 || effectiveRange.charAt(prevCharPos) === '\xA0' ||
                                    effectiveRange.charAt(prevCharPos) === ' ') {
                                    matchInfo = {
                                        macroPosition: idx,
                                        macroText: c,
                                        macroSelectedElement: selected,
                                        macroSelectedPath: path,
                                        macroSelectedOffset: offset,
                                        macroHasTrailingSpace: hasTrailingSpace
                                    };
                                }
                            }
                        });
                        if (matchInfo) {
                            return matchInfo;
                        }
                    }
                }
    
                function getContentEditableSelectedPath(ctx) {
                    var sel = getWindowSelection(ctx);
                    var selected = sel.anchorNode;
                    var path = [];
                    var offset;
                    if (selected != null) {
                        var i;
                        var ce = selected.contentEditable;
                        while (selected !== null && ce !== 'true') {
                            i = getNodePositionInParent(ctx, selected);
                            path.push(i);
                            selected = selected.parentNode;
                            if (selected !== null) {
                                ce = selected.contentEditable;
                            }
                        }
                        path.reverse();
                        offset = sel.getRangeAt(0).startOffset;
                        return {
                            selected: selected,
                            path: path,
                            offset: offset
                        };
                    }
                }
    
                function getTriggerInfo(ctx, triggerCharSet, requireLeadingSpace, menuAlreadyActive, hasTrailingSpace) {
                    var selected, path, offset;
                    if (selectedElementIsTextAreaOrInput(ctx)) {
                        selected = getDocument(ctx).activeElement;
                    } else {
                        var selectionInfo = getContentEditableSelectedPath(ctx);
                        if (selectionInfo) {
                            selected = selectionInfo.selected;
                            path = selectionInfo.path;
                            offset = selectionInfo.offset;
                        }
                    }
                    var effectiveRange = getTextPrecedingCurrentSelection(ctx);
                    if (effectiveRange !== undefined && effectiveRange !== null) {
                        var mostRecentTriggerCharPos = -1;
                        var triggerChar;
                        triggerCharSet.forEach(function(c) {
                            var idx = effectiveRange.lastIndexOf(c);
                            if (idx > mostRecentTriggerCharPos) {
                                mostRecentTriggerCharPos = idx;
                                triggerChar = c;
                            }
                        });
                        if (mostRecentTriggerCharPos >= 0 &&
                            (
                                mostRecentTriggerCharPos === 0 ||
                                !requireLeadingSpace ||
                                /[\xA0\s]/g.test(
                                    effectiveRange.substring(
                                        mostRecentTriggerCharPos - 1,
                                        mostRecentTriggerCharPos)
                                )
                            )
                        ) {
                            var currentTriggerSnippet = effectiveRange.substring(mostRecentTriggerCharPos + 1,
                                effectiveRange.length);
                            triggerChar = effectiveRange.substring(mostRecentTriggerCharPos, mostRecentTriggerCharPos + 1);
                            var firstSnippetChar = currentTriggerSnippet.substring(0, 1);
                            var leadingSpace = currentTriggerSnippet.length > 0 &&
                                (
                                    firstSnippetChar === ' ' ||
                                    firstSnippetChar === '\xA0'
                                );
                            if (hasTrailingSpace) {
                                currentTriggerSnippet = currentTriggerSnippet.trim();
                            }
                            if (!leadingSpace && (menuAlreadyActive || !(/[\xA0\s]/g.test(currentTriggerSnippet)))) {
                                return {
                                    mentionPosition: mostRecentTriggerCharPos,
                                    mentionText: currentTriggerSnippet,
                                    mentionSelectedElement: selected,
                                    mentionSelectedPath: path,
                                    mentionSelectedOffset: offset,
                                    mentionTriggerChar: triggerChar
                                };
                            }
                        }
                    }
                }
    
                function getWindowSelection(ctx) {
                    if (!ctx) {
                        return window.getSelection();
                    } else {
                        return ctx.iframe.contentWindow.getSelection();
                    }
                }
    
                function getDocument(ctx) {
                    if (!ctx) {
                        return document;
                    } else {
                        return ctx.iframe.contentWindow.document;
                    }
                }
    
                function getTextPrecedingCurrentSelection(ctx) {
                    var text;
                    if (selectedElementIsTextAreaOrInput(ctx)) {
                        var textComponent = getDocument(ctx).activeElement;
                        var startPos = textComponent.selectionStart;
                        text = textComponent.value.substring(0, startPos);
                    } else {
                        var selectedElem = getWindowSelection(ctx).anchorNode;
                        if (selectedElem != null) {
                            var workingNodeContent = selectedElem.textContent;
                            var selectStartOffset = getWindowSelection(ctx).getRangeAt(0).startOffset;
                            if (selectStartOffset >= 0) {
                                text = workingNodeContent.substring(0, selectStartOffset);
                            }
                        }
                    }
                    return text;
                }
    
                function getContentEditableCaretPosition(ctx, selectedNodePosition) {
                    var markerTextChar = '\ufeff';
                    var markerEl, markerId = 'sel_' + new Date().getTime() + '_' + Math.random().toString().substr(2);
                    var range;
                    var sel = getWindowSelection(ctx);
                    var prevRange = sel.getRangeAt(0);
                    range = getDocument(ctx).createRange();
                    range.setStart(sel.anchorNode, selectedNodePosition);
                    range.setEnd(sel.anchorNode, selectedNodePosition);
                    range.collapse(false);
                    markerEl = getDocument(ctx).createElement('span');
                    markerEl.id = markerId;
                    markerEl.appendChild(getDocument(ctx).createTextNode(markerTextChar));
                    range.insertNode(markerEl);
                    sel.removeAllRanges();
                    sel.addRange(prevRange);
                    var coordinates = {
                        left: 0,
                        top: markerEl.offsetHeight
                    };
                    localToGlobalCoordinates(ctx, markerEl, coordinates);
                    markerEl.parentNode.removeChild(markerEl);
                    return coordinates;
                }
    
                function localToGlobalCoordinates(ctx, element, coordinates) {
                    var obj = element;
                    var iframe = ctx ? ctx.iframe : null;
                    while (obj) {
                        coordinates.left += obj.offsetLeft;
                        coordinates.top += obj.offsetTop;
                        if (obj !== getDocument().body) {
                            coordinates.top -= obj.scrollTop;
                            coordinates.left -= obj.scrollLeft;
                        }
                        obj = obj.offsetParent;
                        if (!obj && iframe) {
                            obj = iframe;
                            iframe = null;
                        }
                    }
                }
    
                function getTextAreaOrInputUnderlinePosition(ctx, element, position) {
                    var properties = [
                        'direction',
                        'boxSizing',
                        'width',
                        'height',
                        'overflowX',
                        'overflowY',
                        'borderTopWidth',
                        'borderRightWidth',
                        'borderBottomWidth',
                        'borderLeftWidth',
                        'paddingTop',
                        'paddingRight',
                        'paddingBottom',
                        'paddingLeft',
                        'fontStyle',
                        'fontVariant',
                        'fontWeight',
                        'fontStretch',
                        'fontSize',
                        'fontSizeAdjust',
                        'lineHeight',
                        'fontFamily',
                        'textAlign',
                        'textTransform',
                        'textIndent',
                        'textDecoration',
                        'letterSpacing',
                        'wordSpacing'
                    ];
                    var isFirefox = (window.mozInnerScreenX !== null);
                    var div = getDocument(ctx).createElement('div');
                    div.id = 'input-textarea-caret-position-mirror-div';
                    getDocument(ctx).body.appendChild(div);
                    var style = div.style;
                    var computed = window.getComputedStyle ? getComputedStyle(element) : element.currentStyle;
                    style.whiteSpace = 'pre-wrap';
                    if (element.nodeName !== 'INPUT') {
                        style.wordWrap = 'break-word';
                    }
                    style.position = 'absolute';
                    style.visibility = 'hidden';
                    properties.forEach(function(prop) {
                        style[prop] = computed[prop];
                    });
                    if (isFirefox) {
                        style.width = (parseInt(computed.width) - 2) + 'px';
                        if (element.scrollHeight > parseInt(computed.height))
                            style.overflowY = 'scroll';
                    } else {
                        style.overflow = 'hidden';
                    }
                    div.textContent = element.value.substring(0, position);
                    if (element.nodeName === 'INPUT') {
                        div.textContent = div.textContent.replace(/\s/g, '\u00a0');
                    }
                    var span = getDocument(ctx).createElement('span');
                    span.textContent = element.value.substring(position) || '.';
                    div.appendChild(span);
                    var coordinates = {
                        top: span.offsetTop + parseInt(computed.borderTopWidth) + parseInt(computed.fontSize),
                        left: span.offsetLeft + parseInt(computed.borderLeftWidth)
                    };
                    localToGlobalCoordinates(ctx, element, coordinates);
                    getDocument(ctx).body.removeChild(div);
                    return coordinates;
                }
                return {
                    popUnderMention: popUnderMention,
                    replaceMacroText: replaceMacroText,
                    replaceTriggerText: replaceTriggerText,
                    getMacroMatch: getMacroMatch,
                    getTriggerInfo: getTriggerInfo,
                    selectElement: selectElement,
                    getTextAreaOrInputUnderlinePosition: getTextAreaOrInputUnderlinePosition,
                    getTextPrecedingCurrentSelection: getTextPrecedingCurrentSelection,
                    getContentEditableSelectedPath: getContentEditableSelectedPath,
                    getNodePositionInParent: getNodePositionInParent,
                    getContentEditableCaretPosition: getContentEditableCaretPosition,
                    pasteHtml: pasteHtml,
                    resetSelection: resetSelection,
                    scrollIntoView: scrollIntoView
                };
            }]);
        angular.module("mentio").run(["$templateCache", function($templateCache) {
            $templateCache.put("mentio-menu.tpl.html", "<style>\n.scrollable-menu {\n    height: auto;\n    max-height: 300px;\n    overflow: auto;\n}\n\n.menu-highlighted {\n    font-weight: bold;\n}\n</style>\n<ul class=\"dropdown-menu scrollable-menu\" style=\"display:block\">\n    <li mentio-menu-item=\"item\" ng-repeat=\"item in items track by $index\">\n        <a class=\"text-primary\" ng-bind-html=\"item.label | mentioHighlight:typedTerm:\'menu-highlighted\' | unsafe\"></a>\n    </li>\n</ul>");
        }]);
    })();
    /*! RESOURCE: /scripts/sn/common/stream/_module.js */
    angular.module("sn.common.stream", ['sn.base', 'ng.amb', 'sn.messaging', 'sn.common.glide', 'ngSanitize',
        'sn.common.avatar', 'sn.common.ui.popover', 'mentio', 'sn.common.controls', 'sn.common.user_profile',
        'sn.common.datetime', 'sn.common.mention', 'sn.common.ui'
    ]);
    angular.module("sn.stream.direct", ['sn.common.stream']);;
    /*! RESOURCE: /scripts/sn/common/stream/controller.Stream.js */
    angular.module("sn.common.stream").controller("Stream", function($scope, snRecordWatcher, $timeout) {
        var isForm = NOW.sysId.length > 0;
        $scope.showCommentsAndWorkNotes = isForm;
        $scope.sessions = {};
        $scope.recordStreamOpen = false;
        $scope.streamHidden = true;
        $scope.recordSysId = '';
        $scope.recordDisplayValue = '';
        $scope.$on('record.updated', onRecordUpdated);
        $scope.$on('sn.sessions', onSessions);
        $timeout(function() {
            if (isForm)
                snRecordWatcher.initRecord(NOW.targetTable, NOW.sysId);
            else
                snRecordWatcher.initList(NOW.targetTable, NOW.tableQuery);
        }, 100);
        $scope.controls = {
            showRecord: function($event, entry, sysId) {
                if (sysId !== '')
                    return;
                $scope.recordSysId = entry.document_id;
                $scope.recordDisplayValue = entry.display_value;
                $scope.recordStreamOpen = true;
                $scope.streamHidden = true;
            },
            openRecord: function() {
                var targetFrame = window.self;
                var url = NOW.targetTable + ".do?sys_id=" + $scope.recordSysId;
                if (NOW.linkTarget == 'form_pane') {
                    url += "&sysparm_clear_stack=true";
                    window.parent.CustomEvent.fireTop(
                        "glide:nav_open_url", {
                            url: url,
                            openInForm: true
                        });
                    return;
                }
                if (NOW.streamLinkTarget == 'parent' || NOW.concourse == 'true')
                    targetFrame = window.parent;
                targetFrame.location = url;
            },
            openAttachment: function(event, sysId) {
                event.stopPropagation();
                var url = "/sys_attachment.do?view=true&sys_id=" + sysId;
                var newTab = window.open(url, '_blank');
                newTab.focus();
            }
        };
        $scope.sessionCount = function() {
            $scope.sessions.length = Object.keys($scope.sessions.data).length;
            return $scope.sessions.length;
        };
    
        function onSessions(name, sessions) {
            $scope.sessions.data = sessions;
            $scope.sessionCount();
        }
    
        function onRecordUpdated(name, data) {}
        $scope.showListStream = function() {
            $scope.recordStreamOpen = false;
            $scope.recordHidden = false;
            $scope.streamHidden = false;
            angular.element('div.list-stream-record').velocity('snTransition.streamSlideRight', {
                duration: 400
            });
            angular.element('[streamType="list"]').velocity('snTransition.slideIn', {
                duration: 400,
                complete: function(element) {
                    angular.element(element).css({
                        display: 'block'
                    });
                }
            });
        };
        $scope.$watch(function() {
            return angular.element('div.list-stream-record').length
        }, function(newValue, oldValue) {
            if (newValue == 1) {
                angular.element('div.list-stream-record').delay(100).velocity('snTransition.streamSlideLeft', {
                    begin: function(element) {
                        angular.element(element).css({
                            visibility: 'visible'
                        });
                        angular.element('.list-stream-record-header').css({
                            visibility: 'visible'
                        });
                    },
                    duration: 400,
                    complete: function(element) {
                        angular.element(element).css({
                            transform: "translateX(0)"
                        });
                        angular.element(element).scrollTop(0);
                        angular.element(element).css({
                            transform: "initial"
                        });
                    }
                });
            }
        });
    });;
    /*! RESOURCE: /scripts/sn/common/stream/directive.snStream.js */
    angular.module("sn.common.stream").directive("snStream", function(getTemplateUrl, $http, $templateRequest, $compile) {
        "use strict";
        return {
            restrict: "E",
            replace: true,
            scope: {
                table: "=",
                query: "=?",
                sysId: "=?",
                active: "=",
                controls: "=?",
                showCommentsAndWorkNotes: "=?",
                previousActivity: "=?",
                sessions: "=",
                attachments: "=",
                board: "=",
                formJournalFields: "=",
                useMultipleInputs: "=",
                preferredInput: "=",
                labels: "=",
                subStream: "=",
                expandEntries: "=",
                pageSize: "=",
                maxEntries: "@"
            },
            templateUrl: getTemplateUrl("ng_activity_stream.xml"),
            controller: function($scope, $attrs, nowStream, snRecordPresence, snCustomEvent, userPreferences, $window, $q, $timeout, snMention) {
                var stream;
                var processor = $attrs.processor || "list_history";
                var interval;
                var FROM_LIST = 'from_list';
                var FROM_FORM = 'from_form';
                var source = $scope.sysId ? FROM_FORM : FROM_LIST;
                var amb = false;
                var _firstPoll = true;
                var _firstPollTimeout;
                var primaryJournalFieldOrder = ["comments", "work_notes"];
                var primaryJournalField = null;
                $scope.defaultShowCommentsAndWorkNotes = ($scope.sysId != null && !angular.isUndefined($scope.sysId) && $scope.sysId.length > 0);
                $scope.canWriteWorkNotes = false;
                $scope.inputTypeValue = "";
                $scope.entryTemplate = getTemplateUrl($attrs.template || "list_stream_entry");
                $scope.allFields = null;
                $scope.fields = null;
                $scope.fieldColor = "transparent";
                $scope.multipleInputs = $scope.useMultipleInputs;
                $scope.members = [];
                $scope.members.loading = true;
                var mentionMap = {};
                $scope.selectAtMention = function(item) {
                    if (item.termLengthIsZero)
                        return (item.name || "") + "\n";
                    mentionMap[item.name] = item.sys_id;
                    return "@[" + item.name + "]";
                };
                var typingTimer;
                $scope.searchMembersAsync = function(term) {
                    $scope.members = [];
                    $scope.members.loading = true;
                    $timeout.cancel(typingTimer);
                    if (term.length === 0) {
                        $scope.members = [{
                            termLengthIsZero: true
                        }];
                        $scope.members.loading = false;
                    } else {
                        typingTimer = $timeout(function() {
                            snMention.retrieveMembers($scope.table, $scope.sysId, term).then(function(members) {
                                $scope.members = members;
                                $scope.members.loading = false;
                            }, function() {
                                $scope.members = [{
                                    termLengthIsZero: true
                                }];
                                $scope.members.loading = false;
                            });
                        }, 500);
                    }
                };
                $scope.expandMentions = function(text) {
                    return stream.expandMentions(text, mentionMap)
                }
                $scope.reduceMentions = function(text) {
                    if (!text)
                        return text;
                    var regexMentionParts = /[\w\d\s/\']+/gi;
                    text = text.replace(/@\[[\w\d\s]+:[\w\d\s/\']+\]/gi, function(mention) {
                        var mentionParts = mention.match(regexMentionParts);
                        if (mentionParts.length === 2) {
                            var name = mentionParts[1];
                            var userID = mentionParts[0];
                            mentionMap[name] = userID;
                            return "@[" + name + "]";
                        }
                        return mentionParts;
                    });
                    return text;
                }
                $scope.parseMentions = function(entry) {
                    var regexMentionParts = /[\w\d\s/\']+/gi;
                    entry = entry.replace(/@\[[\w\d\s]+:[\w\d\s/\']+\]/gi, function(mention) {
                        var mentionParts = mention.match(regexMentionParts);
                        if (mentionParts.length === 2) {
                            return '<a class="at-mention at-mention-user-' + mentionParts[0] + '">@' + mentionParts[1] + '</a>';
                        }
                        return mentionParts;
                    });
                    return entry;
                };
                $scope.parseLinks = function(text) {
                    var regexLinks = /@L\[([^|]+?)\|([^\]]*)]/gi;
                    return text.replace(regexLinks, "<a href='$1' target='_blank'>$2</a>");
                };
                $scope.parseSpecial = function(text) {
                    var parsedText = $scope.parseLinks(text);
                    parsedText = $scope.parseMentions(parsedText);
                    return parsedText;
                };
                $scope.$watch('active', function(n, o) {
                    if (n === o)
                        return;
                    if ($scope.active)
                        startPolling();
                    else
                        cancelStream();
                });
                $scope.defaultControls = {
                    getTitle: function(entry) {
                        if (entry && entry.short_description) {
                            return entry.short_description;
                        } else if (entry && entry.shortDescription) {
                            return entry.shortDescription;
                        }
                    },
                    showCreatedBy: function() {
                        return true;
                    },
                    hideCommentLabel: function(journal) {
                        return false;
                    },
                    showRecord: function($event, entry) {},
                    showRecordLink: function() {
                        return true;
                    }
                };
                if ($scope.controls) {
                    for (var attr in $scope.controls) {
                        $scope.defaultControls[attr] = $scope.controls[attr];
                    }
                }
                $scope.controls = $scope.defaultControls;
                if ($scope.showCommentsAndWorkNotes === undefined) {
                    $scope.showCommentsAndWorkNotes = $scope.defaultShowCommentsAndWorkNotes;
                }
                snCustomEvent.observe('sn.stream.change_input_display', function(table, display) {
                    if (table != $scope.table)
                        return;
                    $scope.showCommentsAndWorkNotes = display;
                    $scope.$apply();
                });
                $scope.$on("$destroy", function() {
                    cancelStream();
                });
                $scope.$on('sn.stream.interval', function($event, time) {
                    interval = time;
                    reschedulePoll();
                });
                $scope.$on("sn.stream.tap", function() {
                    if (stream)
                        stream.tap();
                    else
                        startPolling();
                });
                $scope.$on('window_visibility_change', function($event, hidden) {
                    interval = (hidden) ? 120000 : undefined;
                    reschedulePoll();
                });
                $scope.$on("sn.stream.refresh", function(event, data) {
                    stream._successCallback(data.response);
                });
                $scope.$on("sn.stream.reload", function() {
                    startPolling();
                });
                $scope.$on('sn.stream.input_value', function(otherScope, value) {
                    $scope.inputTypeValue = value;
                });
                $scope.$watchCollection('[table, query, sysId]', startPolling);
                $scope.changeInputType = function(field) {
                    $scope.inputType = field.checked ? field.name : primaryJournalField;
                    userPreferences.setPreference('glide.ui.' + $scope.table + '.stream_input', $scope.preferredInput);
                };
                $scope.$watch('inputType', function() {
                    if (!$scope.inputType || !$scope.preferredInput)
                        return;
                    $scope.preferredInput = $scope.inputType;
                });
                $scope.submitCheck = function(event) {
                    var key = event.keyCode || event.which;
                    if (key === 13) {
                        $scope.postJournalEntryForCurrent(event);
                    }
                };
                $scope.postJournalEntry = function(type, entry, event) {
                    type = type || primaryJournalFieldOrder[0];
                    event.stopPropagation();
                    var requestTable = $scope.table || "board:" + $scope.board.sys_id;
                    stream.insertForEntry(type, entry.journalText, requestTable, entry.document_id);
                    entry.journalText = "";
                    entry.commentBoxVisible = false;
                    snRecordPresence.termPresence();
                };
                $scope.postJournalEntryForCurrent = function(event) {
                    event.stopPropagation();
                    var entries = [];
                    if ($scope.multipleInputs) {
                        angular.forEach($scope.fields, function(item) {
                            if (!item.value)
                                return;
                            entries.push({
                                field: item.name,
                                text: item.value
                            });
                        })
                    } else {
                        entries.push({
                            field: $scope.inputType,
                            text: $scope.inputTypeValue
                        })
                    }
                    var request = stream.insertEntries(entries, $scope.table, $scope.sysId, mentionMap);
                    if (request) {
                        request.then(function() {
                            for (var i = 0; i < entries.length; i++) {
                                fireInsertEvent(entries[i].field, entries[i].text);
                            }
                        });
                    }
                    clearInputs();
                    return false;
                };
    
                function fireInsertEvent(name, value) {
                    snCustomEvent.fire('sn.stream.insert', name, value);
                }
    
                function clearInputs() {
                    $scope.inputTypeValue = "";
                    angular.forEach($scope.fields, function(item) {
                        if (item.value)
                            item.filled = true;
                        item.value = "";
                    });
                }
                $scope.showCommentBox = function(entry, event) {
                    event.stopPropagation();
                    if (entry !== $scope.selectedEntry)
                        $scope.closeEntry();
                    $scope.selectedEntry = entry;
                    entry.commentBoxVisible = !entry.commentBoxVisible;
                    if (entry.commentBoxVisible) {
                        snRecordPresence.initPresence($scope.table, entry.document_id);
                    }
                };
                $scope.showMore = function(journal, event) {
                    event.stopPropagation();
                    journal.showMore = true;
                };
                $scope.showLess = function(journal, event) {
                    event.stopPropagation();
                    journal.showMore = false;
                };
                $scope.closeEntry = function() {
                    if ($scope.selectedEntry)
                        $scope.selectedEntry.commentBoxVisible = false;
                };
                $scope.previewAttachment = function(evt, attachmentUrl) {
                    snCustomEvent.fire('sn.attachment.preview', evt, attachmentUrl);
                }
                $scope.$on('sn.sessions', function(someOtherScope, sessions) {
                    if ($scope.selectedEntry && $scope.selectedEntry.commentBoxVisible)
                        $scope.selectedEntry.sessions = sessions;
                });
                $scope.$watch("inputTypeValue", function() {
                    emitTyping($scope.inputTypeValue);
                });
                $scope.$watch("selectedEntry.journalText", function(newValue) {
                    if ($scope.selectedEntry)
                        emitTyping(newValue || "");
                });
                $scope.$watch('useMultipleInputs', function() {
                    setMultipleInputs();
                });
    
                function emitTyping(inputValue) {
                    var status = inputValue.length ? "typing" : "viewing";
                    $scope.$emit("record.typing", {
                        status: status,
                        value: inputValue,
                        table: $scope.table,
                        sys_id: $scope.sys_id
                    });
                }
    
                function preloadedData() {
                    if (typeof window.NOW.snActivityStreamData === 'object' &&
                        window.NOW.snActivityStreamData[$scope.table + '_' + $scope.sysId]) {
                        _firstPoll = false;
                        var data = window.NOW.snActivityStreamData[$scope.table + '_' + $scope.sysId];
                        stream = nowStream.create($scope.table, $scope.query, $scope.sysId,
                            processor, interval, source, $scope.attachments);
                        stream.callback = onPoll;
                        stream.preRequestCallback = beforePoll;
                        stream.lastTimestamp = data.sys_timestamp;
                        if (data.entries && data.entries.length) {
                            stream.lastEntry = angular.copy(data.entries[0]);
                        }
                        _firstPollTimeout = setTimeout(function() {
                            stream.poll(onPoll, beforePoll);
                            _firstPollTimeout = false;
                        }, NOW.stream_poll_interval * 1000 || 5000);
                        beforePoll();
                        onPoll(data);
                        return true;
                    }
                    return false;
                }
    
                function scheduleNewPoll(lastTimestamp) {
                    cancelStream();
                    stream = nowStream.create($scope.table, $scope.query, $scope.sysId,
                        processor, interval, source, $scope.attachments);
                    stream.lastTimestamp = lastTimestamp;
                    stream.poll(onPoll, beforePoll);
                }
    
                function reschedulePoll() {
                    var lastTimestamp = stream ? stream.lastTimestamp : 0;
                    if (cancelStream()) {
                        scheduleNewPoll(lastTimestamp);
                    }
                }
    
                function reset() {
                    $scope.loaded = false;
                    startPolling();
                }
    
                function startPolling() {
                    if ($scope.loading && !$scope.loaded)
                        return;
                    if (!$scope.active)
                        return;
                    $scope.entries = [];
                    $scope.allEntries = [];
                    $scope.showAllEntriesButton = false;
                    $scope.loaded = false;
                    $scope.loading = true;
                    if (_firstPoll && preloadedData()) {
                        return;
                    }
                    scheduleNewPoll();
                }
    
                function onPoll(response) {
                    $scope.loading = false;
                    if (response.primary_fields)
                        primaryJournalFieldOrder = response.primary_fields;
                    if (!$scope.fields)
                        processFields(response.fields);
                    processEntries(response.entries);
                    if (!$scope.loaded) {
                        $scope.loaded = true;
                        $scope.$emit("sn.stream.loaded", response);
                    }
                }
    
                function beforePoll() {
                    $scope.$emit("sn.stream.requested");
                }
    
                function processFields(fields) {
                    if (!fields || !fields.length)
                        return;
                    $scope.fields = {};
                    $scope.allFields = fields;
                    setShowAllFields();
                    $scope.fieldsVisible = 0;
                    angular.forEach(fields, function(field) {
                        if (!field.isJournal)
                            return;
                        $scope.fields[field.name] = field;
                        $scope.fields[field.name].visible = $scope.formJournalFields ? false : true;
                        if ($scope.fields[field.name].visible)
                            $scope.fieldsVisible++;
                        var fieldColor = field.color;
                        if (fieldColor)
                            fieldColor = field.color.replace(/background-color: /, '')
                        if (!fieldColor || fieldColor == 'transparent')
                            fieldColor = null;
                        $scope.fields[field.name].color = fieldColor;
                    });
                    setFieldVisibility();
                    setPrimaryJournalField();
                    setMultipleInputs();
                }
                $scope.$watch('formJournalFields', function() {
                    setFieldVisibility();
                    setPrimaryJournalField();
                    setMultipleInputs();
                }, true);
    
                function setFieldVisibility() {
                    if (!$scope.formJournalFields || !$scope.fields || !$scope.showCommentsAndWorkNotes)
                        return;
                    $scope.fieldsVisible = 0;
                    angular.forEach($scope.formJournalFields, function(formField) {
                        if (!$scope.fields[formField.name])
                            return;
                        $scope.fields[formField.name].value = formField.value;
                        $scope.fields[formField.name].mandatory = formField.mandatory;
                        $scope.fields[formField.name].label = formField.label;
                        $scope.fields[formField.name].messages = formField.messages;
                        $scope.fields[formField.name].visible = formField.visible && !formField.readonly;
                        if ($scope.fields[formField.name].visible)
                            $scope.fieldsVisible++;
                    });
                }
    
                function setPrimaryJournalField() {
                    if (!$scope.fields || !$scope.showCommentsAndWorkNotes)
                        return;
                    angular.forEach($scope.fields, function(item) {
                        item.isPrimary = false;
                    });
                    var visibleFields = Object.keys($scope.fields).filter(function(item) {
                        return $scope.fields[item].visible;
                    });
                    if (visibleFields.indexOf($scope.preferredInput) != -1) {
                        $scope.inputType = $scope.preferredInput;
                        $scope.fields[$scope.preferredInput].checked = true;
                    }
                    for (var i = 0; i < primaryJournalFieldOrder.length; i++) {
                        var fieldName = primaryJournalFieldOrder[i];
                        if (visibleFields.indexOf(fieldName) != -1) {
                            $scope.fields[fieldName].isPrimary = true;
                            primaryJournalField = fieldName;
                            if (!$scope.inputType)
                                $scope.inputType = fieldName;
                            break;
                        }
                    }
                    if (!$scope.inputType && visibleFields.length > 0) {
                        primaryJournalField = visibleFields[0];
                        $scope.inputType = primaryJournalField;
                        $scope.fields[primaryJournalField].isPrimary = true;
                    }
                }
    
                function setShowAllFields() {
                    $scope.showAllFields = $scope.allFields && !$scope.allFields.some(function(item) {
                        return !item.isActive;
                    });
                    $scope.hideAllFields = !$scope.allFields || !$scope.allFields.some(function(item) {
                        return item.isActive;
                    });
                }
                $scope.setPrimary = function(entry) {
                    angular.forEach($scope.fields, function(item) {
                        item.checked = false;
                    });
                    for (var i = 0; i < primaryJournalFieldOrder.length; i++) {
                        var fieldName = primaryJournalFieldOrder[i];
                        if (entry.writable_journal_fields.indexOf(fieldName) != -1) {
                            entry.primaryJournalField = fieldName;
                            entry.inputType = fieldName;
                            return;
                        }
                    }
                    if (!entry.inputType) {
                        var primaryField = entry.writable_journal_fields[0];
                        entry.primaryJournalField = primaryField;
                        entry.inputType = primaryField;
                    }
                }
                $scope.updateFieldVisibilityAll = function() {
                    $scope.showAllFields = !$scope.showAllFields;
                    angular.forEach($scope.allFields, function(item) {
                        item.isActive = $scope.showAllFields;
                    });
                    $scope.updateFieldVisibility();
                }
                $scope.updateFieldVisibility = function() {
                    var activeFields = $scope.allFields.filter(function(item) {
                        return item.isActive;
                    }).map(function(item) {
                        return item.name + ',' + item.isActive;
                    });
                    setShowAllFields();
                    userPreferences
                        .setPreference($scope.table + '.activity.filter', activeFields.join(';'))
                        .then(function() {
                            reset();
                        })
                }
                $scope.configureAvailableFields = function() {
                    $window.personalizer($scope.table, 'activity', $scope.sysId);
                }
                $scope.toggleMultipleInputs = function(val) {
                    userPreferences.setPreference('glide.ui.activity_stream.multiple_inputs', val ? 'true' : 'false')
                        .then(function() {
                            $scope.useMultipleInputs = val;
                            setMultipleInputs();
                        });
                }
                $scope.changeEntryInputType = function(fieldName, entry) {
                    var checked = $scope.fields[fieldName].checked;
                    entry.inputType = checked ? fieldName : entry.primaryJournalField;
                }
    
                function processEntries(entries) {
                    if (!entries || !entries.length)
                        return;
                    entries = entries.reverse();
                    var newEntries = [];
                    angular.forEach(entries, function(entry) {
                        var entriesToAdd = [entry];
                        if (entry.attachment) {
                            entry.type = getAttachmentType(entry.attachment);
                            entry.attachment.filesize = formatSize(entry.attachment.size_bytes);
                            entry.attachment.extension = getAttachmentExt(entry.attachment);
                        } else if (entry.is_email === true) {
                            entry.email = {};
                            var allFields = entry.entries.custom;
                            for (var i = 0; i < allFields.length; i++) {
                                entry.email[allFields[i].field_name] = {
                                    label: allFields[i]['field_label'],
                                    displayValue: allFields[i]['new_value']
                                };
                            }
                            entry['entries'].custom = [];
                        } else if ($scope.sysId) {
                            entriesToAdd = extractJournalEntries(entry);
                        } else {
                            entriesToAdd = handleJournalEntriesWithoutExtraction(entry);
                        }
                        if (entriesToAdd instanceof Array) {
                            entriesToAdd.forEach(function(e) {
                                $scope.entries.unshift(e);
                                newEntries.unshift(e);
                            });
                        } else {
                            $scope.entries.unshift(entriesToAdd);
                            newEntries.unshift(entriesToAdd)
                        }
                        if (source != FROM_FORM)
                            $scope.entries = $scope.entries.slice(0, 49);
                        if ($scope.maxEntries != undefined) {
                            var maxNumEntries = parseInt($scope.maxEntries, 10);
                            $scope.entries = $scope.entries.slice(0, maxNumEntries);
                        }
                    });
                    if ($scope.loaded) {
                        $scope.$emit("sn.stream.new_entries", newEntries);
                        triggerResize();
                    } else if ($scope.pageSize && $scope.entries.length > $scope.pageSize)
                        setUpPaging();
                }
    
                function setUpPaging() {
                    $scope.showAllEntriesButton = true;
                    $scope.allEntries = $scope.entries;
                    $scope.entries = [];
                    loadEntries(0, $scope.pageSize);
                }
                $scope.loadMore = function() {
                    if ($scope.entries.length + $scope.pageSize > $scope.allEntries.length) {
                        $scope.loadAll();
                        return;
                    }
                    loadEntries($scope.loadedEntries, $scope.loadedEntries + $scope.pageSize);
                }
                $scope.loadAll = function() {
                    $scope.showAllEntriesButton = false;
                    loadEntries($scope.loadedEntries, $scope.allEntries.length);
                }
    
                function loadEntries(start, end) {
                    $scope.entries = $scope.entries.concat($scope.allEntries.slice(start, end));
                    $scope.loadedEntries = $scope.entries.length;
                }
    
                function getAttachmentType(attachment) {
                    if (attachment.content_type.startsWith('image/'))
                        return 'attachment-image';
                    return 'attachment';
                }
    
                function getAttachmentExt(attachment) {
                    var filename = attachment.file_name;
                    return filename.substring(filename.lastIndexOf('.') + 1);
                }
    
                function formatSize(bytes) {
                    if (bytes >= 1000000000)
                        bytes = (bytes / 1000000000).toFixed(2) + ' GB';
                    else if (bytes >= 1000000)
                        bytes = (bytes / 1000000).toFixed(2) + ' MB';
                    else if (bytes >= 1000)
                        bytes = (bytes / 1000).toFixed(2) + ' KB';
                    else if (bytes > 1)
                        bytes = bytes + ' bytes';
                    else if (bytes == 1)
                        bytes = bytes + ' byte';
                    else
                        bytes = '';
                    return bytes;
                }
    
                function handleJournalEntriesWithoutExtraction(oneLargeEntry) {
                    if (oneLargeEntry.entries.journal.length === 0)
                        return oneLargeEntry;
                    for (var i = 0; i < oneLargeEntry.entries.journal.length; i++) {
                        newLinesToBR(oneLargeEntry.entries.journal);
                    }
                    return oneLargeEntry;
                }
    
                function extractJournalEntries(oneLargeEntry) {
                    var smallerEntries = [];
                    if (oneLargeEntry.entries.journal.length === 0)
                        return oneLargeEntry;
                    for (var i = 0; i < oneLargeEntry.entries.journal.length; i++) {
                        var journalEntry = angular.copy(oneLargeEntry);
                        journalEntry.entries.journal = journalEntry.entries.journal.slice(i, i + 1);
                        newLinesToBR(journalEntry.entries.journal);
                        journalEntry.entries.changes = [];
                        journalEntry.type = 'journal';
                        smallerEntries.unshift(journalEntry);
                    }
                    oneLargeEntry.entries.journal = [];
                    oneLargeEntry.type = 'changes';
                    if (oneLargeEntry.entries.changes.length > 0)
                        smallerEntries.unshift(oneLargeEntry);
                    return smallerEntries;
                }
    
                function newLinesToBR(entries) {
                    angular.forEach(entries, function(item) {
                        if (!item.new_value)
                            return;
                        item.new_value = item.new_value.replace(/\n/g, '<br/>');
                    });
                }
    
                function cancelStream() {
                    if (_firstPollTimeout) {
                        clearTimeout(_firstPollTimeout);
                        _firstPollTimeout = false;
                    }
                    if (!stream)
                        return false;
                    stream.cancel();
                    stream = null;
                    return true; 
                }
    
                function setMultipleInputs() {
                    $scope.multipleInputs = $scope.useMultipleInputs;
                    if ($scope.useMultipleInputs === true || !$scope.formJournalFields) {
                        return;
                    }
                    var numAffectedFields = 0;
                    angular.forEach($scope.formJournalFields, function(item) {
                        if (item.mandatory || item.value)
                            numAffectedFields++;
                    });
                    if (numAffectedFields > 0)
                        $scope.multipleInputs = true;
                }
    
                function triggerResize() {
                    if (window._frameChanged)
                        setTimeout(_frameChanged, 0);
                }
            },
            link: function(scope, element, attrs) {
                element.on("click", ".at-mention", function(evt) {
                    var userID = angular.element(evt.target).attr('class').substring("at-mention at-mention-user-".length);
                    $http({
                        url: '/api/now/form/mention/user/' + userID,
                        method: "GET"
                    }).then(function(response) {
                        scope.showPopover = true;
                        scope.mentionPopoverProfile = response.data.result;
                        scope.clickEvent = evt;
                    }, function() {
                        $http({
                            url: '/api/now/live/profiles/' + userID,
                            method: "GET"
                        }).then(function(response) {
                            scope.showPopover = true;
                            var tempProfile = response.data.result;
                            tempProfile.userID = tempProfile.sys_id = response.data.result.document;
                            scope.mentionPopoverProfile = tempProfile;
                            scope.mentionPopoverProfile.sysID = response.data.result["userID"];
                            scope.clickEvent = evt;
                        })
                    });
                });
                scope.toggleEmailIframe = function(email, event) {
                    email.expanded = email.expanded ? false : true;
                    event.preventDefault();
                };
                $templateRequest(getTemplateUrl(attrs.template || "list_stream_entry")).then(function(template) {
                    var elm = element.find("#activity-stream-unordered-list-entries");
                    var entries = angular.element("<li class=\"h-card h-card_md h-card_comments\" ng-click=\"controls.showRecord($event, entry, sysId)\" ng-repeat=\"entry in entries | orderBy:'-sys_created_on'\" ng-animate=\"'sn-animate-stream-entry'\">" + template + "</li>");
                    elm.append(entries);
                    $compile(entries)(scope);
                });
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/stream/directive.snExpandedEmail.js */
    angular.module("sn.common.stream").directive("snExpandedEmail", function() {
        "use strict";
        return {
            restrict: "E",
            replace: true,
            scope: {
                email: "="
            },
            template: "<iframe style='width: 100%;' class='card' src='{{::emailBodySrc}}'></iframe>",
            controller: function($scope) {
                $scope.emailBodySrc = "email_display.do?email_id=" + $scope.email.sys_id.displayValue;
            },
            link: function(scope, element) {
                element.load(function() {
                    var bodyHeight = $j(this).get(0).contentWindow.document.body.scrollHeight + "px";
                    $j(this).height(bodyHeight);
                });
            }
        };
    });;
    /*! RESOURCE: /scripts/app.form_presence/controller.formStream.js */
    (function() {
        var journalModel = {};
        window.journalModel = journalModel;
        CustomEvent.observe('sn.form.journal_field.add', function(name, mandatory, readonly, visible, value, label) {
            journalModel[name] = {
                name: name,
                mandatory: mandatory,
                readonly: readonly,
                visible: visible,
                value: value,
                label: label,
                messages: []
            };
        });
        CustomEvent.observe('sn.form.journal_field.readonly', function(name, readonly) {
            modifyJournalAttribute(name, "readonly", readonly);
        });
        CustomEvent.observe('sn.form.journal_field.value', function(name, value) {
            modifyJournalAttribute(name, "value", value);
        });
        CustomEvent.observe('sn.form.journal_field.mandatory', function(name, mandatory) {
            modifyJournalAttribute(name, "mandatory", mandatory);
        });
        CustomEvent.observe('sn.form.journal_field.visible', function(name, visible) {
            modifyJournalAttribute(name, "visible", visible);
        });
        CustomEvent.observe('sn.form.journal_field.label', function(name, visible) {
            modifyJournalAttribute(name, "label", visible);
        });
        CustomEvent.observe('sn.form.journal_field.show_msg', function(input, message, type) {
            var messages = journalModel[input]['messages'].concat([{
                type: type,
                message: message
            }]);
            modifyJournalAttribute(input, 'messages', messages);
        });
        CustomEvent.observe('sn.form.journal_field.hide_msg', function(input, clearAll) {
            if (journalModel[input]['messages'].length == 0)
                return;
            var desiredValue = [];
            if (!clearAll)
                desiredValue = journalModel[input]['messages'].slice(1);
            modifyJournalAttribute(input, 'messages', desiredValue);
        });
        CustomEvent.observe('sn.form.hide_all_field_msg', function(type) {
            var fields = Object.keys(journalModel);
            for (var i = 0; i < fields.length; i++) {
                var f = fields[i];
                if (journalModel[f].messages.length == 0)
                    continue;
                var messages = [];
                if (type) {
                    var oldMessages = angular.copy(journalModel[f].messages);
                    for (var j = 0; j < oldMessages.length; j++) {
                        if (oldMessages[j].type != type)
                            messages.push(oldMessages[j]);
                    }
                }
                modifyJournalAttribute(f, 'messages', messages);
            }
        });
        CustomEvent.observe('sn.stream.insert', function(field, text) {
            if (typeof window.g_form !== "undefined")
                g_form.getControl(field).value = NOW.STREAM_VALUE_KEY + text;
        });
    
        function modifyJournalAttribute(field, prop, value) {
            journalModel[field][prop] = value;
            CustomEvent.fire('sn.form.journal_field.changed');
        }
        angular.module('sn.common.stream').controller('formStream', function($scope, snCustomEvent) {
            $scope.formJournalFields = journalModel;
            $scope.formJournalFieldsVisible = false;
            setUp();
            snCustomEvent.observe('sn.form.journal_field.changed', function() {
                setUp();
                if (!$scope.$$phase)
                    $scope.$apply();
            });
    
            function setUp() {
                setInputValue();
            }
    
            function setInputValue() {
                angular.forEach($scope.formJournalFields, function(item) {
                    if (typeof window.g_form === "undefined")
                        return;
                    item.value = g_form.getValue(item.name);
                    if (!item.readonly && item.visible && (item.value !== undefined || item.value !== null)) {
                        $scope.$broadcast('sn.stream.input_value', item.value);
                        return false;
                    }
                });
            }
        })
    })();;
    /*! RESOURCE: /scripts/app.form_presence/directive.scroll_form.js */
    angular.module('sn.common.stream').directive('scrollFrom', function() {
        "use strict";
        var SCROLL_TOP_PAD = 10;
        return {
            restrict: 'A',
            link: function($scope, $element, $attrs) {
                var target = $attrs.scrollFrom;
                $j(target).click(function(evt) {
                    if (window.g_form) {
                        var tab = g_form._getTabNameForElement($element);
                        if (tab)
                            g_form.activateTab(tab);
                    }
                    var $scrollRoot = $element.closest('.form-group');
                    if ($scrollRoot.length === 0)
                        $scrollRoot = $element;
                    var $scrollParent = $scrollRoot.scrollParent();
                    var offset = $element.offset().top - $scrollParent.offset().top - SCROLL_TOP_PAD + $scrollParent.scrollTop();
                    $scrollParent.animate({
                        scrollTop: offset
                    }, '500', 'swing');
                    evt.stopPropagation();
                })
            }
        }
    });;;;
    /*! RESOURCE: /scripts/angularjs-1.4/sn/common/attachments/js_includes_attachments.js */
    /*! RESOURCE: /scripts/angularjs-1.4/thirdparty/angular-file-upload/angular-file-upload-all.js */
    (function() {
        function patchXHR(fnName, newFn) {
            window.XMLHttpRequest.prototype[fnName] = newFn(window.XMLHttpRequest.prototype[fnName]);
        }
        if (window.XMLHttpRequest && !window.XMLHttpRequest.__isFileAPIShim) {
            patchXHR('setRequestHeader', function(orig) {
                return function(header, value) {
                    if (header === '__setXHR_') {
                        var val = value(this);
                        if (val instanceof Function) {
                            val(this);
                        }
                    } else {
                        orig.apply(this, arguments);
                    }
                }
            });
        }
        var angularFileUpload = angular.module('angularFileUpload', []);
        angularFileUpload.version = '3.1.2';
        angularFileUpload.service('$upload', ['$http', '$q', '$timeout', function($http, $q, $timeout) {
            function sendHttp(config) {
                config.method = config.method || 'POST';
                config.headers = config.headers || {};
                config.transformRequest = config.transformRequest || function(data, headersGetter) {
                    if (window.ArrayBuffer && data instanceof window.ArrayBuffer) {
                        return data;
                    }
                    return $http.defaults.transformRequest[0](data, headersGetter);
                };
                var deferred = $q.defer();
                var promise = deferred.promise;
                config.headers['__setXHR_'] = function() {
                    return function(xhr) {
                        if (!xhr) return;
                        config.__XHR = xhr;
                        config.xhrFn && config.xhrFn(xhr);
                        xhr.upload.addEventListener('progress', function(e) {
                            e.config = config;
                            deferred.notify ? deferred.notify(e) : promise.progress_fn && $timeout(function() {
                                promise.progress_fn(e)
                            });
                        }, false);
                        xhr.upload.addEventListener('load', function(e) {
                            if (e.lengthComputable) {
                                e.config = config;
                                deferred.notify ? deferred.notify(e) : promise.progress_fn && $timeout(function() {
                                    promise.progress_fn(e)
                                });
                            }
                        }, false);
                    };
                };
                $http(config).then(function(r) {
                    deferred.resolve(r)
                }, function(e) {
                    deferred.reject(e)
                }, function(n) {
                    deferred.notify(n)
                });
                promise.success = function(fn) {
                    promise.then(function(response) {
                        fn(response.data, response.status, response.headers, config);
                    });
                    return promise;
                };
                promise.error = function(fn) {
                    promise.then(null, function(response) {
                        fn(response.data, response.status, response.headers, config);
                    });
                    return promise;
                };
                promise.progress = function(fn) {
                    promise.progress_fn = fn;
                    promise.then(null, null, function(update) {
                        fn(update);
                    });
                    return promise;
                };
                promise.abort = function() {
                    if (config.__XHR) {
                        $timeout(function() {
                            config.__XHR.abort();
                        });
                    }
                    return promise;
                };
                promise.xhr = function(fn) {
                    config.xhrFn = (function(origXhrFn) {
                        return function() {
                            origXhrFn && origXhrFn.apply(promise, arguments);
                            fn.apply(promise, arguments);
                        }
                    })(config.xhrFn);
                    return promise;
                };
                return promise;
            }
            this.upload = function(config) {
                config.headers = config.headers || {};
                config.headers['Content-Type'] = undefined;
                var origTransformRequest = config.transformRequest;
                config.transformRequest = config.transformRequest ?
                    (Object.prototype.toString.call(config.transformRequest) === '[object Array]' ?
                        config.transformRequest : [config.transformRequest]) : [];
                config.transformRequest.push(function(data, headerGetter) {
                    var formData = new FormData();
                    var allFields = {};
                    for (var key in config.fields) allFields[key] = config.fields[key];
                    if (data) allFields['data'] = data;
                    if (config.formDataAppender) {
                        for (var key in allFields) {
                            config.formDataAppender(formData, key, allFields[key]);
                        }
                    } else {
                        for (var key in allFields) {
                            var val = allFields[key];
                            if (val !== undefined) {
                                if (Object.prototype.toString.call(val) === '[object String]') {
                                    formData.append(key, val);
                                } else {
                                    if (config.sendObjectsAsJsonBlob && typeof val === 'object') {
                                        formData.append(key, new Blob([val], {
                                            type: 'application/json'
                                        }));
                                    } else {
                                        formData.append(key, JSON.stringify(val));
                                    }
                                }
                            }
                        }
                    }
                    if (config.file != null) {
                        var fileFormName = config.fileFormDataName || 'file';
                        if (Object.prototype.toString.call(config.file) === '[object Array]') {
                            var isFileFormNameString = Object.prototype.toString.call(fileFormName) === '[object String]';
                            for (var i = 0; i < config.file.length; i++) {
                                formData.append(isFileFormNameString ? fileFormName : fileFormName[i], config.file[i],
                                    (config.fileName && config.fileName[i]) || config.file[i].name);
                            }
                        } else {
                            formData.append(fileFormName, config.file, config.fileName || config.file.name);
                        }
                    }
                    return formData;
                });
                return sendHttp(config);
            };
            this.http = function(config) {
                return sendHttp(config);
            };
        }]);
        angularFileUpload.directive('ngFileSelect', ['$parse', '$timeout', '$compile',
            function($parse, $timeout, $compile) {
                return {
                    restrict: 'AEC',
                    require: '?ngModel',
                    link: function(scope, elem, attr, ngModel) {
                        handleFileSelect(scope, elem, attr, ngModel, $parse, $timeout, $compile);
                    }
                }
            }
        ]);
    
        function handleFileSelect(scope, elem, attr, ngModel, $parse, $timeout, $compile) {
            function isInputTypeFile() {
                return elem[0].tagName.toLowerCase() === 'input' && elem.attr('type') && elem.attr('type').toLowerCase() === 'file';
            }
            var watchers = [];
    
            function watchForRecompile(attrVal) {
                $timeout(function() {
                    if (elem.parent().length) {
                        watchers.push(scope.$watch(attrVal, function(val, oldVal) {
                            if (val != oldVal) {
                                recompileElem();
                            }
                        }));
                    }
                });
            }
    
            function recompileElem() {
                var clone = elem.clone();
                if (elem.attr('__afu_gen__')) {
                    angular.element(document.getElementById(elem.attr('id').substring(1))).remove();
                }
                if (elem.parent().length) {
                    for (var i = 0; i < watchers.length; i++) {
                        watchers[i]();
                    }
                    elem.replaceWith(clone);
                    $compile(clone)(scope);
                }
                return clone;
            }
    
            function bindAttr(bindAttr, attrName) {
                if (bindAttr) {
                    watchForRecompile(bindAttr);
                    var val = $parse(bindAttr)(scope);
                    if (val) {
                        elem.attr(attrName, val);
                        attr[attrName] = val;
                    } else {
                        elem.attr(attrName, null);
                        delete attr[attrName];
                    }
                }
            }
            bindAttr(attr.ngMultiple, 'multiple');
            bindAttr(attr.ngAccept, 'ng-accept');
            bindAttr(attr.ngCapture, 'capture');
            if (attr['ngFileSelect'] != '') {
                attr.ngFileChange = attr.ngFileSelect;
            }
    
            function onChangeFn(evt) {
                var files = [],
                    fileList, i;
                fileList = evt.__files_ || (evt.target && evt.target.files);
                updateModel(fileList, attr, ngModel, scope, evt);
            };
            var fileElem = elem;
            if (!isInputTypeFile()) {
                fileElem = angular.element('<input type="file">')
                if (elem.attr('multiple')) fileElem.attr('multiple', elem.attr('multiple'));
                if (elem.attr('accept')) fileElem.attr('accept', elem.attr('accept'));
                if (elem.attr('capture')) fileElem.attr('capture', elem.attr('capture'));
                for (var key in attr) {
                    if (key.indexOf('inputFile') == 0) {
                        var name = key.substring('inputFile'.length);
                        name = name[0].toLowerCase() + name.substring(1);
                        fileElem.attr(name, attr[key]);
                    }
                }
                fileElem.css('width', '0px').css('height', '0px').css('position', 'absolute').css('padding', 0).css('margin', 0)
                    .css('overflow', 'hidden').attr('tabindex', '-1').css('opacity', 0).attr('__afu_gen__', true);
                elem.attr('__refElem__', true);
                fileElem[0].__refElem__ = elem[0];
                elem.parent()[0].insertBefore(fileElem[0], elem[0])
                elem.css('overflow', 'hidden');
                elem.bind('click', function(e) {
                    if (!resetAndClick(e)) {
                        fileElem[0].click();
                    }
                });
            } else {
                elem.bind('click', resetAndClick);
            }
    
            function resetAndClick(evt) {
                if (fileElem[0].value != null && fileElem[0].value != '') {
                    fileElem[0].value = null;
                    if (navigator.userAgent.indexOf("Trident/7") === -1) {
                        onChangeFn({
                            target: {
                                files: []
                            }
                        });
                    }
                }
                if (!elem.attr('__afu_clone__')) {
                    if (navigator.appVersion.indexOf("MSIE 10") !== -1 || navigator.userAgent.indexOf("Trident/7") !== -1) {
                        var clone = recompileElem();
                        clone.attr('__afu_clone__', true);
                        clone[0].click();
                        evt.preventDefault();
                        evt.stopPropagation();
                        return true;
                    }
                } else {
                    elem.attr('__afu_clone__', null);
                }
            }
            fileElem.bind('change', onChangeFn);
            elem.on('$destroy', function() {
                for (var i = 0; i < watchers.length; i++) {
                    watchers[i]();
                }
                if (elem[0] != fileElem[0]) fileElem.remove();
            });
            watchers.push(scope.$watch(attr.ngModel, function(val, oldVal) {
                if (val != oldVal && (val == null || !val.length)) {
                    if (navigator.appVersion.indexOf("MSIE 10") !== -1) {
                        recompileElem();
                    } else {
                        fileElem[0].value = null;
                    }
                }
            }));
    
            function updateModel(fileList, attr, ngModel, scope, evt) {
                var files = [],
                    rejFiles = [];
                var accept = $parse(attr.ngAccept)(scope);
                var regexp = angular.isString(accept) && accept ? new RegExp(globStringToRegex(accept), 'gi') : null;
                var acceptFn = regexp ? null : attr.ngAccept;
                for (var i = 0; i < fileList.length; i++) {
                    var file = fileList.item(i);
                    if ((!regexp || file.type.match(regexp) || (file.name != null && file.name.match(regexp))) &&
                        (!acceptFn || $parse(acceptFn)(scope, {
                            $file: file,
                            $event: evt
                        }))) {
                        files.push(file);
                    } else {
                        rejFiles.push(file);
                    }
                }
                $timeout(function() {
                    if (ngModel) {
                        $parse(attr.ngModel).assign(scope, files);
                        ngModel && ngModel.$setViewValue(files != null && files.length == 0 ? '' : files);
                        if (attr.ngModelRejected) {
                            $parse(attr.ngModelRejected).assign(scope, rejFiles);
                        }
                    }
                    if (attr.ngFileChange && attr.ngFileChange != "") {
                        $parse(attr.ngFileChange)(scope, {
                            $files: files,
                            $rejectedFiles: rejFiles,
                            $event: evt
                        });
                    }
                });
            }
        }
        angularFileUpload.directive('ngFileDrop', ['$parse', '$timeout', '$location', function($parse, $timeout, $location) {
            return {
                restrict: 'AEC',
                require: '?ngModel',
                link: function(scope, elem, attr, ngModel) {
                    handleDrop(scope, elem, attr, ngModel, $parse, $timeout, $location);
                }
            }
        }]);
        angularFileUpload.directive('ngNoFileDrop', function() {
            return function(scope, elem, attr) {
                if (dropAvailable()) elem.css('display', 'none')
            }
        });
        angularFileUpload.directive('ngFileDropAvailable', ['$parse', '$timeout', function($parse, $timeout) {
            return function(scope, elem, attr) {
                if (dropAvailable()) {
                    var fn = $parse(attr['ngFileDropAvailable']);
                    $timeout(function() {
                        fn(scope);
                    });
                }
            }
        }]);
    
        function handleDrop(scope, elem, attr, ngModel, $parse, $timeout, $location) {
            var available = dropAvailable();
            if (attr['dropAvailable']) {
                $timeout(function() {
                    scope.dropAvailable ? scope.dropAvailable.value = available : scope.dropAvailable = available;
                });
            }
            if (!available) {
                if ($parse(attr.hideOnDropNotAvailable)(scope) != false) {
                    elem.css('display', 'none');
                }
                return;
            }
            var leaveTimeout = null;
            var stopPropagation = $parse(attr.stopPropagation)(scope);
            var dragOverDelay = 1;
            var accept = $parse(attr.ngAccept)(scope) || attr.accept;
            var regexp = angular.isString(accept) && accept ? new RegExp(globStringToRegex(accept), 'gi') : null;
            var acceptFn = regexp ? null : attr.ngAccept;
            var actualDragOverClass;
            elem[0].addEventListener('dragover', function(evt) {
                evt.preventDefault();
                if (stopPropagation) evt.stopPropagation();
                if (navigator.userAgent.indexOf("Chrome") > -1) {
                    var b = evt.dataTransfer.effectAllowed;
                    evt.dataTransfer.dropEffect = ('move' === b || 'linkMove' === b) ? 'move' : 'copy';
                }
                $timeout.cancel(leaveTimeout);
                if (!scope.actualDragOverClass) {
                    actualDragOverClass = calculateDragOverClass(scope, attr, evt);
                }
                elem.addClass(actualDragOverClass);
            }, false);
            elem[0].addEventListener('dragenter', function(evt) {
                evt.preventDefault();
                if (stopPropagation) evt.stopPropagation();
            }, false);
            elem[0].addEventListener('dragleave', function(evt) {
                leaveTimeout = $timeout(function() {
                    elem.removeClass(actualDragOverClass);
                    actualDragOverClass = null;
                }, dragOverDelay || 1);
            }, false);
            if (attr['ngFileDrop'] != '') {
                attr.ngFileChange = attr['ngFileDrop'];
            }
            elem[0].addEventListener('drop', function(evt) {
                evt.preventDefault();
                if (stopPropagation) evt.stopPropagation();
                elem.removeClass(actualDragOverClass);
                actualDragOverClass = null;
                extractFiles(evt, function(files, rejFiles) {
                    $timeout(function() {
                        if (ngModel) {
                            $parse(attr.ngModel).assign(scope, files);
                            ngModel && ngModel.$setViewValue(files != null && files.length == 0 ? '' : files);
                        }
                        if (attr['ngModelRejected']) {
                            if (scope[attr.ngModelRejected]) {
                                $parse(attr.ngModelRejected).assign(scope, rejFiles);
                            }
                        }
                    });
                    $timeout(function() {
                        $parse(attr.ngFileChange)(scope, {
                            $files: files,
                            $rejectedFiles: rejFiles,
                            $event: evt
                        });
                    });
                }, $parse(attr.allowDir)(scope) != false, attr.multiple || $parse(attr.ngMultiple)(scope));
            }, false);
    
            function calculateDragOverClass(scope, attr, evt) {
                var valid = true;
                if (regexp || acceptFn) {
                    var items = evt.dataTransfer.items;
                    if (items != null) {
                        for (var i = 0; i < items.length && valid; i++) {
                            valid = valid && (items[i].kind == 'file' || items[i].kind == '') &&
                                ((acceptFn && $parse(acceptFn)(scope, {
                                        $file: items[i],
                                        $event: evt
                                    })) ||
                                    (regexp && (items[i].type != null && items[i].type.match(regexp)) ||
                                        (items[i].name != null && items[i].name.match(regexp))));
                        }
                    }
                }
                var clazz = $parse(attr.dragOverClass)(scope, {
                    $event: evt
                });
                if (clazz) {
                    if (clazz.delay) dragOverDelay = clazz.delay;
                    if (clazz.accept) clazz = valid ? clazz.accept : clazz.reject;
                }
                return clazz || attr['dragOverClass'] || 'dragover';
            }
    
            function extractFiles(evt, callback, allowDir, multiple) {
                var files = [],
                    rejFiles = [],
                    items = evt.dataTransfer.items,
                    processing = 0;
    
                function addFile(file) {
                    if ((!regexp || file.type.match(regexp) || (file.name != null && file.name.match(regexp))) &&
                        (!acceptFn || $parse(acceptFn)(scope, {
                            $file: file,
                            $event: evt
                        }))) {
                        files.push(file);
                    } else {
                        rejFiles.push(file);
                    }
                }
                if (items && items.length > 0 && $location.protocol() != 'file') {
                    for (var i = 0; i < items.length; i++) {
                        if (items[i].webkitGetAsEntry && items[i].webkitGetAsEntry() && items[i].webkitGetAsEntry().isDirectory) {
                            var entry = items[i].webkitGetAsEntry();
                            if (entry.isDirectory && !allowDir) {
                                continue;
                            }
                            if (entry != null) {
                                traverseFileTree(files, entry);
                            }
                        } else {
                            var f = items[i].getAsFile();
                            if (f != null) addFile(f);
                        }
                        if (!multiple && files.length > 0) break;
                    }
                } else {
                    var fileList = evt.dataTransfer.files;
                    if (fileList != null) {
                        for (var i = 0; i < fileList.length; i++) {
                            addFile(fileList.item(i));
                            if (!multiple && files.length > 0) break;
                        }
                    }
                }
                var delays = 0;
                (function waitForProcess(delay) {
                    $timeout(function() {
                        if (!processing) {
                            if (!multiple && files.length > 1) {
                                var i = 0;
                                while (files[i].type == 'directory') i++;
                                files = [files[i]];
                            }
                            callback(files, rejFiles);
                        } else {
                            if (delays++ * 10 < 20 * 1000) {
                                waitForProcess(10);
                            }
                        }
                    }, delay || 0)
                })();
    
                function traverseFileTree(files, entry, path) {
                    if (entry != null) {
                        if (entry.isDirectory) {
                            var filePath = (path || '') + entry.name;
                            addFile({
                                name: entry.name,
                                type: 'directory',
                                path: filePath
                            });
                            var dirReader = entry.createReader();
                            var entries = [];
                            processing++;
                            var readEntries = function() {
                                dirReader.readEntries(function(results) {
                                    try {
                                        if (!results.length) {
                                            for (var i = 0; i < entries.length; i++) {
                                                traverseFileTree(files, entries[i], (path ? path : '') + entry.name + '/');
                                            }
                                            processing--;
                                        } else {
                                            entries = entries.concat(Array.prototype.slice.call(results || [], 0));
                                            readEntries();
                                        }
                                    } catch (e) {
                                        processing--;
                                        console.error(e);
                                    }
                                }, function() {
                                    processing--;
                                });
                            };
                            readEntries();
                        } else {
                            processing++;
                            entry.file(function(file) {
                                try {
                                    processing--;
                                    file.path = (path ? path : '') + file.name;
                                    addFile(file);
                                } catch (e) {
                                    processing--;
                                    console.error(e);
                                }
                            }, function(e) {
                                processing--;
                            });
                        }
                    }
                }
            }
        }
    
        function dropAvailable() {
            var div = document.createElement('div');
            return ('draggable' in div) && ('ondrop' in div);
        }
    
        function globStringToRegex(str) {
            if (str.length > 2 && str[0] === '/' && str[str.length - 1] === '/') {
                return str.substring(1, str.length - 1);
            }
            var split = str.split(','),
                result = '';
            if (split.length > 1) {
                for (var i = 0; i < split.length; i++) {
                    result += '(' + globStringToRegex(split[i]) + ')';
                    if (i < split.length - 1) {
                        result += '|'
                    }
                }
            } else {
                if (str.indexOf('.') == 0) {
                    str = '*' + str;
                }
                result = '^' + str.replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + '-]', 'g'), '\\$&') + '$';
                result = result.replace(/\\\*/g, '.*').replace(/\\\?/g, '.');
            }
            return result;
        }
        var ngFileUpload = angular.module('ngFileUpload', []);
        for (var key in angularFileUpload) {
            ngFileUpload[key] = angularFileUpload[key];
        }
    })();
    (function() {
        var hasFlash = function() {
            try {
                var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
                if (fo) return true;
            } catch (e) {
                if (navigator.mimeTypes['application/x-shockwave-flash'] != undefined) return true;
            }
            return false;
        }
    
        function patchXHR(fnName, newFn) {
            window.XMLHttpRequest.prototype[fnName] = newFn(window.XMLHttpRequest.prototype[fnName]);
        };
        if ((window.XMLHttpRequest && !window.FormData) || (window.FileAPI && FileAPI.forceLoad)) {
            var initializeUploadListener = function(xhr) {
                if (!xhr.__listeners) {
                    if (!xhr.upload) xhr.upload = {};
                    xhr.__listeners = [];
                    var origAddEventListener = xhr.upload.addEventListener;
                    xhr.upload.addEventListener = function(t, fn, b) {
                        xhr.__listeners[t] = fn;
                        origAddEventListener && origAddEventListener.apply(this, arguments);
                    };
                }
            }
            patchXHR('open', function(orig) {
                return function(m, url, b) {
                    initializeUploadListener(this);
                    this.__url = url;
                    try {
                        orig.apply(this, [m, url, b]);
                    } catch (e) {
                        if (e.message.indexOf('Access is denied') > -1) {
                            this.__origError = e;
                            orig.apply(this, [m, '_fix_for_ie_crossdomain__', b]);
                        }
                    }
                }
            });
            patchXHR('getResponseHeader', function(orig) {
                return function(h) {
                    return this.__fileApiXHR && this.__fileApiXHR.getResponseHeader ? this.__fileApiXHR.getResponseHeader(h) : (orig == null ? null : orig.apply(this, [h]));
                };
            });
            patchXHR('getAllResponseHeaders', function(orig) {
                return function() {
                    return this.__fileApiXHR && this.__fileApiXHR.getAllResponseHeaders ? this.__fileApiXHR.getAllResponseHeaders() : (orig == null ? null : orig.apply(this));
                }
            });
            patchXHR('abort', function(orig) {
                return function() {
                    return this.__fileApiXHR && this.__fileApiXHR.abort ? this.__fileApiXHR.abort() : (orig == null ? null : orig.apply(this));
                }
            });
            patchXHR('setRequestHeader', function(orig) {
                return function(header, value) {
                    if (header === '__setXHR_') {
                        initializeUploadListener(this);
                        var val = value(this);
                        if (val instanceof Function) {
                            val(this);
                        }
                    } else {
                        this.__requestHeaders = this.__requestHeaders || {};
                        this.__requestHeaders[header] = value;
                        orig.apply(this, arguments);
                    }
                }
            });
    
            function redefineProp(xhr, prop, fn) {
                try {
                    Object.defineProperty(xhr, prop, {
                        get: fn
                    });
                } catch (e) {}
            }
            patchXHR('send', function(orig) {
                return function() {
                    var xhr = this;
                    if (arguments[0] && arguments[0].__isFileAPIShim) {
                        var formData = arguments[0];
                        var config = {
                            url: xhr.__url,
                            jsonp: false,
                            cache: true,
                            complete: function(err, fileApiXHR) {
                                xhr.__completed = true;
                                if (!err && xhr.__listeners['load'])
                                    xhr.__listeners['load']({
                                        type: 'load',
                                        loaded: xhr.__loaded,
                                        total: xhr.__total,
                                        target: xhr,
                                        lengthComputable: true
                                    });
                                if (!err && xhr.__listeners['loadend'])
                                    xhr.__listeners['loadend']({
                                        type: 'loadend',
                                        loaded: xhr.__loaded,
                                        total: xhr.__total,
                                        target: xhr,
                                        lengthComputable: true
                                    });
                                if (err === 'abort' && xhr.__listeners['abort'])
                                    xhr.__listeners['abort']({
                                        type: 'abort',
                                        loaded: xhr.__loaded,
                                        total: xhr.__total,
                                        target: xhr,
                                        lengthComputable: true
                                    });
                                if (fileApiXHR.status !== undefined) redefineProp(xhr, 'status', function() {
                                    return (fileApiXHR.status == 0 && err && err !== 'abort') ? 500 : fileApiXHR.status
                                });
                                if (fileApiXHR.statusText !== undefined) redefineProp(xhr, 'statusText', function() {
                                    return fileApiXHR.statusText
                                });
                                redefineProp(xhr, 'readyState', function() {
                                    return 4
                                });
                                if (fileApiXHR.response !== undefined) redefineProp(xhr, 'response', function() {
                                    return fileApiXHR.response
                                });
                                var resp = fileApiXHR.responseText || (err && fileApiXHR.status == 0 && err !== 'abort' ? err : undefined);
                                redefineProp(xhr, 'responseText', function() {
                                    return resp
                                });
                                redefineProp(xhr, 'response', function() {
                                    return resp
                                });
                                if (err) redefineProp(xhr, 'err', function() {
                                    return err
                                });
                                xhr.__fileApiXHR = fileApiXHR;
                                if (xhr.onreadystatechange) xhr.onreadystatechange();
                                if (xhr.onload) xhr.onload();
                            },
                            fileprogress: function(e) {
                                e.target = xhr;
                                xhr.__listeners['progress'] && xhr.__listeners['progress'](e);
                                xhr.__total = e.total;
                                xhr.__loaded = e.loaded;
                                if (e.total === e.loaded) {
                                    var _this = this
                                    setTimeout(function() {
                                        if (!xhr.__completed) {
                                            xhr.getAllResponseHeaders = function() {};
                                            _this.complete(null, {
                                                status: 204,
                                                statusText: 'No Content'
                                            });
                                        }
                                    }, FileAPI.noContentTimeout || 10000);
                                }
                            },
                            headers: xhr.__requestHeaders
                        }
                        config.data = {};
                        config.files = {}
                        for (var i = 0; i < formData.data.length; i++) {
                            var item = formData.data[i];
                            if (item.val != null && item.val.name != null && item.val.size != null && item.val.type != null) {
                                config.files[item.key] = item.val;
                            } else {
                                config.data[item.key] = item.val;
                            }
                        }
                        setTimeout(function() {
                            if (!hasFlash()) {
                                throw 'Adode Flash Player need to be installed. To check ahead use "FileAPI.hasFlash"';
                            }
                            xhr.__fileApiXHR = FileAPI.upload(config);
                        }, 1);
                    } else {
                        if (this.__origError) {
                            throw this.__origError;
                        }
                        orig.apply(xhr, arguments);
                    }
                }
            });
            window.XMLHttpRequest.__isFileAPIShim = true;
            var addFlash = function(elem) {
                if (!hasFlash()) {
                    throw 'Adode Flash Player need to be installed. To check ahead use "FileAPI.hasFlash"';
                }
                var el = angular.element(elem);
                if (!el.attr('disabled')) {
                    var hasFileSelect = false;
                    for (var i = 0; i < el[0].attributes.length; i++) {
                        var attrib = el[0].attributes[i];
                        if (attrib.name.indexOf('file-select') !== -1) {
                            hasFileSelect = true;
                            break;
                        }
                    }
                    if (!el.hasClass('js-fileapi-wrapper') && (hasFileSelect || el.attr('__afu_gen__') != null)) {
                        el.addClass('js-fileapi-wrapper');
                        if (el.attr('__afu_gen__') != null) {
                            var ref = (el[0].__refElem__ && angular.element(el[0].__refElem__)) || el;
                            while (ref && !ref.attr('__refElem__')) {
                                ref = angular.element(ref[0].nextSibling);
                            }
                            ref.bind('mouseover', function() {
                                if (el.parent().css('position') === '' || el.parent().css('position') === 'static') {
                                    el.parent().css('position', 'relative');
                                }
                                el.css('position', 'absolute').css('top', ref[0].offsetTop + 'px').css('left', ref[0].offsetLeft + 'px')
                                    .css('width', ref[0].offsetWidth + 'px').css('height', ref[0].offsetHeight + 'px')
                                    .css('padding', ref.css('padding')).css('margin', ref.css('margin')).css('filter', 'alpha(opacity=0)');
                                ref.attr('onclick', '');
                                el.css('z-index', '1000');
                            });
                        }
                    }
                }
            };
            var changeFnWrapper = function(fn) {
                return function(evt) {
                    var files = FileAPI.getFiles(evt);
                    for (var i = 0; i < files.length; i++) {
                        if (files[i].size === undefined) files[i].size = 0;
                        if (files[i].name === undefined) files[i].name = 'file';
                        if (files[i].type === undefined) files[i].type = 'undefined';
                    }
                    if (!evt.target) {
                        evt.target = {};
                    }
                    evt.target.files = files;
                    if (evt.target.files != files) {
                        evt.__files_ = files;
                    }
                    (evt.__files_ || evt.target.files).item = function(i) {
                        return (evt.__files_ || evt.target.files)[i] || null;
                    }
                    if (fn) fn.apply(this, [evt]);
                };
            };
            var isFileChange = function(elem, e) {
                return (e.toLowerCase() === 'change' || e.toLowerCase() === 'onchange') && elem.getAttribute('type') == 'file';
            }
            if (HTMLInputElement.prototype.addEventListener) {
                HTMLInputElement.prototype.addEventListener = (function(origAddEventListener) {
                    return function(e, fn, b, d) {
                        if (isFileChange(this, e)) {
                            addFlash(this);
                            origAddEventListener.apply(this, [e, changeFnWrapper(fn), b, d]);
                        } else {
                            origAddEventListener.apply(this, [e, fn, b, d]);
                        }
                    }
                })(HTMLInputElement.prototype.addEventListener);
            }
            if (HTMLInputElement.prototype.attachEvent) {
                HTMLInputElement.prototype.attachEvent = (function(origAttachEvent) {
                    return function(e, fn) {
                        if (isFileChange(this, e)) {
                            addFlash(this);
                            if (window.jQuery) {
                                angular.element(this).bind('change', changeFnWrapper(null));
                            } else {
                                origAttachEvent.apply(this, [e, changeFnWrapper(fn)]);
                            }
                        } else {
                            origAttachEvent.apply(this, [e, fn]);
                        }
                    }
                })(HTMLInputElement.prototype.attachEvent);
            }
            window.FormData = FormData = function() {
                return {
                    append: function(key, val, name) {
                        if (val.__isFileAPIBlobShim) {
                            val = val.data[0];
                        }
                        this.data.push({
                            key: key,
                            val: val,
                            name: name
                        });
                    },
                    data: [],
                    __isFileAPIShim: true
                };
            };
            window.Blob = Blob = function(b) {
                return {
                    data: b,
                    __isFileAPIBlobShim: true
                };
            };
            (function() {
                if (!window.FileAPI) {
                    window.FileAPI = {};
                }
                if (FileAPI.forceLoad) {
                    FileAPI.html5 = false;
                }
                if (!FileAPI.upload) {
                    var jsUrl, basePath, script = document.createElement('script'),
                        allScripts = document.getElementsByTagName('script'),
                        i, index, src;
                    if (window.FileAPI.jsUrl) {
                        jsUrl = window.FileAPI.jsUrl;
                    } else if (window.FileAPI.jsPath) {
                        basePath = window.FileAPI.jsPath;
                    } else {
                        for (i = 0; i < allScripts.length; i++) {
                            src = allScripts[i].src;
                            index = src.search(/\/angular\-file\-upload[\-a-zA-z0-9\.]*\.js/)
                            if (index > -1) {
                                basePath = src.substring(0, index + 1);
                                break;
                            }
                        }
                    }
                    if (FileAPI.staticPath == null) FileAPI.staticPath = basePath;
                    script.setAttribute('src', jsUrl || basePath + 'FileAPI.min.js');
                    document.getElementsByTagName('head')[0].appendChild(script);
                    FileAPI.hasFlash = hasFlash();
                }
            })();
            FileAPI.disableFileInput = function(elem, disable) {
                if (disable) {
                    elem.removeClass('js-fileapi-wrapper')
                } else {
                    elem.addClass('js-fileapi-wrapper');
                }
            }
        }
        if (!window.FileReader) {
            window.FileReader = function() {
                var _this = this,
                    loadStarted = false;
                this.listeners = {};
                this.addEventListener = function(type, fn) {
                    _this.listeners[type] = _this.listeners[type] || [];
                    _this.listeners[type].push(fn);
                };
                this.removeEventListener = function(type, fn) {
                    _this.listeners[type] && _this.listeners[type].splice(_this.listeners[type].indexOf(fn), 1);
                };
                this.dispatchEvent = function(evt) {
                    var list = _this.listeners[evt.type];
                    if (list) {
                        for (var i = 0; i < list.length; i++) {
                            list[i].call(_this, evt);
                        }
                    }
                };
                this.onabort = this.onerror = this.onload = this.onloadstart = this.onloadend = this.onprogress = null;
                var constructEvent = function(type, evt) {
                    var e = {
                        type: type,
                        target: _this,
                        loaded: evt.loaded,
                        total: evt.total,
                        error: evt.error
                    };
                    if (evt.result != null) e.target.result = evt.result;
                    return e;
                };
                var listener = function(evt) {
                    if (!loadStarted) {
                        loadStarted = true;
                        _this.onloadstart && _this.onloadstart(constructEvent('loadstart', evt));
                    }
                    if (evt.type === 'load') {
                        _this.onloadend && _this.onloadend(constructEvent('loadend', evt));
                        var e = constructEvent('load', evt);
                        _this.onload && _this.onload(e);
                        _this.dispatchEvent(e);
                    } else if (evt.type === 'progress') {
                        var e = constructEvent('progress', evt);
                        _this.onprogress && _this.onprogress(e);
                        _this.dispatchEvent(e);
                    } else {
                        var e = constructEvent('error', evt);
                        _this.onerror && _this.onerror(e);
                        _this.dispatchEvent(e);
                    }
                };
                this.readAsArrayBuffer = function(file) {
                    FileAPI.readAsBinaryString(file, listener);
                }
                this.readAsBinaryString = function(file) {
                    FileAPI.readAsBinaryString(file, listener);
                }
                this.readAsDataURL = function(file) {
                    FileAPI.readAsDataURL(file, listener);
                }
                this.readAsText = function(file) {
                    FileAPI.readAsText(file, listener);
                }
            }
        }
    })();;
    /*! RESOURCE: /scripts/angularjs-1.4/sn/common/attachments/_module.js */
    angular.module('sn.common.attachments', [
        'angularFileUpload',
        'sn.common.util'
    ]);;
    /*! RESOURCE: /scripts/angularjs-1.4/sn/common/attachments/factory.nowAttachmentHandler.js */
    angular.module("sn.common.attachments").factory("nowAttachmentHandler", function($http, nowServer, $upload, $rootScope, $timeout,
        snNotification) {
        "use strict";
        return function(setAttachments, appendError) {
            var self = this;
            self.cardUploading = '';
            self.setAttachments = setAttachments;
            self.appendError = appendError;
            self.ADDED = 'added';
            self.DELETED = 'deleted';
            self.RENAMED = 'renamed';
            self.getAttachmentList = function(action) {
                var url = nowServer.getURL('ngk_attachments', {
                    action: 'list',
                    sys_id: self.tableId,
                    table: self.tableName
                });
                $http.get(url).then(function(response) {
                    var attachments = response.data.files || [];
                    self.setAttachments(attachments, action);
                    if (self.startedUploadingTimeout || self.errorTimeout) {
                        self.stopAllUploading();
                        $rootScope.$broadcast('board.uploading.end');
                    }
                });
            };
            self.stopAllUploading = function() {
                $timeout.cancel(self.errorTimeout);
                $timeout.cancel(self.startedUploadingTimeout);
                hideProgressBar();
                $rootScope.$broadcast("attachment.upload.stop");
            };
            self.onFileSelect = function($files) {
                if (!$files.length)
                    return;
                var url = nowServer.getURL('ngk_attachments', {
                    sys_id: self.tableId,
                    table: self.tableName,
                    action: 'add'
                });
                self.cardUploading = self.tableId;
                self.maxfiles = $files.length;
                self.fileCount = 1;
                self.filesUploaded = self.maxfiles;
                self.startedUploadingTimeout = $timeout(showUploaderDialog, 1500);
                for (var i = 0; i < self.maxfiles; i++) {
                    if (parseInt($files[i].size) > parseInt(self.fileUploadSizeLimit)) {
                        self.stopAllUploading();
                        $rootScope.$broadcast('dialog.upload_too_large.show');
                        return;
                    }
                }
                for (var i = 0; i < self.maxfiles; i++) {
                    $rootScope.$broadcast("attachment.upload.start");
                    var file = $files[i];
                    self.filesUploaded--;
                    self.upload = $upload.upload({
                        url: url,
                        fields: {
                            attachments_modified: 'true',
                            sysparm_table: self.tableName,
                            sysparm_sys_id: self.tableId,
                            sysparm_nostack: 'yes',
                            sysparm_encryption_context: '',
                            sysparm_ck: window.g_ck
                        },
                        fileFormDataName: 'attachFile',
                        file: file
                    }).progress(function(evt) {
                        var percent = parseInt(100.0 * evt.loaded / evt.total, 10);
                        updateProgress(percent);
                    }).success(function(data, status, headers, config) {
                        processError(data);
                        self.stopAllUploading();
                        self.getAttachmentList(self.ADDED);
                        if (self.filesUploaded <= 0) {
                            self.cardUploading = '';
                        }
                    });
                }
            };
            self.downloadAttachment = function(attachment) {
                window.location.href = '/sys_attachment.do?sys_id=' + attachment.sys_id;
            };
            self.viewAttachment = function($event, attachment) {
                var url = window.location.protocol + '//' + window.location.host;
                url += '/sys_attachment.do?sysparm_referring_url=tear_off&view=true&sys_id=' + attachment.sys_id;
                window.open(url, attachment.sys_id,
                    "toolbar=no,menubar=no,personalbar=no,width=800,height=600,scrollbars=yes,resizable=yes");
            };
            self.editAttachment = function($event, attachment) {
                var parent = $($event.currentTarget).closest('.file-attachment');
                var thumbnail = parent.find('.thumbnail');
                var input = parent.find('input');
                var tools = parent.find('.tools');
                var fileName = attachment.file_name;
                if (attachment.file_name.indexOf('.') !== -1) {
                    attachment.ext = fileName.match(/(\.[^\.]+)$/i)[0];
                    fileName = attachment.file_name.replace(/(\.[^\.]+)$/i, '');
                }
                input.val(fileName);
                var w = input.prev().width();
                input.width(w);
                input.prev().hide();
                input.css('display', 'block');
                thumbnail.addClass('state-locked');
                tools.find('.delete-edit').hide();
                tools.find('.rename-cancel').css('display', 'inline-block');
                input.focus();
            }
            self.onKeyDown = function($event, attachment) {
                var keyCode = $event.keyCode;
                if (keyCode === 13) {
                    $event.stopPropagation();
                    $event.preventDefault();
                    self.updateAttachment($event, attachment);
                } else if (keyCode === 27) {
                    $event.stopPropagation();
                    self.updateAttachment($event);
                }
            };
            self.updateAttachment = function($event, attachment) {
                var el = $($event.currentTarget);
                var parent = el.closest('.file-attachment');
                var thumbnail = parent.find('.thumbnail');
                var input = parent.find('input');
                var link = parent.find('a');
                var tools = parent.find('.tools');
                if (attachment) {
                    var fileName = input.val();
                    if (fileName.length) {
                        fileName += attachment.ext;
                        if (fileName !== attachment.file_name) {
                            link.text(fileName);
                            self.renameAttachment(attachment, fileName);
                        }
                    }
                }
                input.hide();
                input.prev().show();
                tools.find('.rename-cancel').hide();
                thumbnail.removeClass('state-locked');
                tools.find('.delete-edit').css('display', 'inline-block');
            };
            self.dismissMsg = function($event, $index, errorMessages) {
                var msg = $($event.currentTarget);
                msg.addClass('remove');
                setTimeout(function() {
                    msg.remove();
                    errorMessages.splice($index, 1);
                }, 500);
            };
            $rootScope.$on("dialog.comment_form.close", function() {
                hideProgressBar();
            });
            self.openSelector = function($event) {
                $event.stopPropagation();
                var target = $($event.currentTarget);
                var input = target.parent().find('input[type=file]');
                input.click();
            }
            self.deleteAttachment = function(attachment) {
                if (attachment && attachment.sys_id) {
                    $('#' + attachment.sys_id).hide();
                    var url = nowServer.getURL('ngk_attachments', {
                        action: 'delete',
                        sys_id: attachment.sys_id
                    });
                    $http.get(url).then(function(response) {
                        processError(response.data);
                        self.getAttachmentList(self.DELETED);
                    });
                }
            };
            self.renameAttachment = function(attachment, newName) {
                $http({
                    url: nowServer.getURL('ngk_attachments'),
                    method: 'POST',
                    params: {
                        action: 'rename',
                        sys_id: attachment.sys_id,
                        new_name: newName
                    }
                }).then(function(response) {
                    processError(response.data);
                    self.getAttachmentList(self.RENAMED);
                });
            };
    
            function showUploaderDialog() {
                $rootScope.$broadcast('board.uploading.start', self.tableId);
            }
    
            function updateProgress(percent) {
                if (self.prevPercent === percent && self.fileCount <= self.maxfiles)
                    return;
                if (self.fileCount <= self.maxfiles) {
                    if (percent > 99)
                        self.fileCount++;
                    if (self.fileCount <= self.maxfiles) {
                        $timeout.cancel(self.errorTimeout);
                        self.errorTimeout = $timeout(broadcastError, 15000);
                        $('.progress-label').text('Uploading file ' + self.fileCount + ' of ' + self.maxfiles);
                        $('.upload-progress').val(percent);
                        $('.progress-wrapper').show();
                    }
                }
                self.prevPercent = percent;
            }
    
            function hideProgressBar() {
                try {
                    $('.progress-wrapper').hide();
                } catch (e) {}
            }
            self.setParams = function(tableName, tableId, fileUploadSizeLimit) {
                self.tableName = tableName;
                self.tableId = tableId;
                self.fileUploadSizeLimit = fileUploadSizeLimit;
            };
    
            function broadcastError() {
                $rootScope.$broadcast('board.uploading.end');
                snNotification.show('error', 'An error occured when trying to upload your file. Please try again.');
                self.stopAllUploading();
            }
    
            function processError(data) {
                if (data.error) {
                    self.appendError({
                        msg: data.error + ' : ',
                        fileName: '"' + data.fileName + '"'
                    });
                }
            }
        };
    });;
    /*! RESOURCE: /scripts/angularjs-1.4/sn/common/attachments/directive.nowAttachmentsList.js */
    angular.module('sn.common.attachments').directive('nowAttachmentsList', function(getTemplateUrl) {
        'use strict';
        return {
            restrict: 'E',
            replace: true,
            templateUrl: getTemplateUrl("attachments_list.xml"),
            link: function(scope, elem, attrs, $parse) {
                scope.icons = {
                    preview: attrs.previewIcon,
                    edit: attrs.editIcon,
                    delete: attrs.deleteIcon,
                    ok: attrs.okIcon,
                    cancel: attrs.cancelIcon
                };
                scope.listClass = "list-group";
                var inline = scope.$eval(attrs.inline);
                if (inline)
                    scope.listClass = "list-inline";
                scope.entryTemplate = getTemplateUrl(attrs.template || "attachment");
            }
        };
    });;
    /*! RESOURCE: /scripts/angularjs-1.4/sn/common/attachments/factory.snAttachmentHandler.js */
    angular.module('sn.common.attachments').factory('snAttachmentHandler', function(urlTools, $http, $upload, $window, $q) {
        "use strict";
        return {
            getViewUrl: getViewUrl,
            create: createAttachmentHandler,
            deleteAttachment: deleteAttachmentBySysID,
            renameAttachment: renameAttachmentBySysID
        };
    
        function getViewUrl(sysId) {
            return '/sys_attachment.do?sys_id=' + sysId;
        }
    
        function deleteAttachmentBySysID(sysID) {
            var url = urlTools.getURL('ngk_attachments', {
                action: 'delete',
                sys_id: sysID
            });
            return $http.get(url);
        }
    
        function renameAttachmentBySysID(sysID, newName) {
            var url = urlTools.getURL('ngk_attachments', {
                action: 'rename',
                sys_id: sysID,
                new_name: newName
            });
            return $http.post(url);
        }
    
        function createAttachmentHandler(tableName, sysID) {
            var _tableName = tableName;
            var _sysID = sysID;
            var _files = [];
    
            function getTableName() {
                return _tableName;
            }
    
            function getSysID() {
                return _sysID;
            }
    
            function getAttachments() {
                var url = urlTools.getURL('ngk_attachments', {
                    action: 'list',
                    sys_id: _sysID,
                    table: _tableName
                });
                return $http.get(url).then(function(response) {
                    var files = response.data.files;
                    if (_files.length == 0) {
                        files.forEach(function(file) {
                            _transformFileResponse(file);
                            _files.push(file);
                        })
                    } else {
                        _files = files;
                    }
                    return _files;
                });
            }
    
            function addAttachment(attachment) {
                _files.unshift(attachment);
            }
    
            function deleteAttachment(attachment) {
                var index = _files.indexOf(attachment);
                if (index !== -1) {
                    return deleteAttachmentBySysID(attachment.sys_id).then(function() {
                        _files.splice(index, 1);
                    });
                }
            }
    
            function uploadAttachments(files, uploadFields) {
                var defer = $q.defer();
                var promises = [];
                var fileData = [];
                angular.forEach(files, function(file) {
                    promises.push(uploadAttachment(file, uploadFields).then(function(response) {
                        fileData.push(response);
                    }));
                });
                $q.all(promises).then(function() {
                    defer.resolve(fileData);
                });
                return defer.promise;
            }
    
            function uploadAttachment(file, uploadFields, uploadMethods) {
                var url = urlTools.getURL('ngk_attachments', {
                    action: 'add',
                    sys_id: _sysID,
                    table: _tableName,
                    load_attachment_record: 'true'
                });
                var fields = {
                    attachments_modified: 'true',
                    sysparm_table: _tableName,
                    sysparm_sys_id: _sysID,
                    sysparm_nostack: 'yes',
                    sysparm_encryption_context: ''
                };
                if (typeof $window.g_ck !== 'undefined') {
                    fields['sysparm_ck'] = $window.g_ck;
                }
                if (uploadFields) {
                    angular.extend(fields, uploadFields);
                }
                var upload = $upload.upload({
                    url: url,
                    fields: fields,
                    fileFormDataName: 'attachFile',
                    file: file
                });
                if (uploadMethods !== undefined) {
                    if (uploadMethods.hasOwnProperty('progress')) {
                        upload.progress(uploadMethods.progress);
                    }
                    if (uploadMethods.hasOwnProperty('success')) {
                        upload.success(uploadMethods.success);
                    }
                    if (uploadMethods.hasOwnProperty('error')) {
                        upload.error(uploadMethods.error);
                    }
                }
                return upload.then(function(response) {
                    var sysFile = response.data;
                    if (sysFile.error) {
                        return $q.reject("Exception when adding attachment: " + sysFile.error);
                    }
                    _transformFileResponse(sysFile);
                    addAttachment(sysFile);
                    return sysFile;
                });
            }
    
            function _transformFileResponse(file) {
                file.isImage = false;
                file.canPreview = false;
                if (file.content_type.indexOf('image') !== -1) {
                    file.isImage = true;
                    if (!file.thumbSrc) {} else if (file.thumbSrc[0] !== '/') {
                        file.thumbSrc = '/' + file.thumbSrc;
                    }
                    file.canPreview = file.content_type.indexOf('tiff') === -1;
                }
                file.viewUrl = getViewUrl(file.sys_id);
            }
            return {
                getSysID: getSysID,
                getTableName: getTableName,
                getAttachments: getAttachments,
                addAttachment: addAttachment,
                deleteAttachment: deleteAttachment,
                uploadAttachment: uploadAttachment,
                uploadAttachments: uploadAttachments
            };
        }
    });;
    /*! RESOURCE: /scripts/angularjs-1.4/sn/common/attachments/directive.snFileUploadInput.js */
    angular.module('sn.common.attachments').directive('snFileUploadInput', function(cabrillo, $document) {
        'use strict';
        return {
            restrict: 'E',
            scope: {
                attachmentHandler: '='
            },
            template: function() {
                var inputTemplate;
                if (cabrillo.isNative()) {
                    inputTemplate = '<button class="{{classNames}}" ng-click="showAttachOptions($event)"><span class="upload-label">{{:: "Add Attachment" | translate}}</span></button>';
                } else {
                    inputTemplate = '<button class="{{classNames}}" ng-file-select="onFileSelect($files)"><span class="upload-label">{{:: "Add Attachment" | translate}}</span></button>';
                }
                return [
                    '<div class="file-upload-input">',
                    inputTemplate,
                    '</div>'
                ].join('');
            },
            controller: function($element, $scope) {
                $scope.classNames = 'btn btn-icon attachment-btn icon-paperclip';
                $scope.showAttachOptions = function($event) {
                    var handler = $scope.attachmentHandler;
                    var target = angular.element($event.currentTarget);
                    var elRect = target[0].getBoundingClientRect();
                    var body = $document[0].body;
                    var rect = {
                        x: elRect.left + body.scrollLeft,
                        y: elRect.top + body.scrollTop,
                        width: elRect.width,
                        height: elRect.height
                    };
                    var options = {
                        sourceRect: rect
                    };
                    cabrillo.attachments.addFile(
                        handler.getTableName(),
                        handler.getSysID(),
                        null,
                        options
                    ).then(function(data) {
                        console.log('Attached new file', data);
                        handler.addAttachment(data);
                    }, function() {
                        console.log('Failed to attach new file');
                    });
                };
                $scope.onFileSelect = function($files) {
                    $scope.attachmentHandler.uploadAttachments($files);
                };
                $scope.showFileSelector = function($event) {
                    $event.stopPropagation();
                    var target = angular.element($event.currentTarget);
                    var input = target.parent().find('input');
                    input.triggerHandler('click');
                };
            }
        }
    });;
    /*! RESOURCE: /scripts/angularjs-1.4/sn/common/attachments/directive.snPasteImageHandler.js */
    angular.module('sn.common.attachments').directive('snPasteImageHandler', function($parse) {
        'use strict';
        return {
            restrict: 'A',
            replace: true,
            link: function(scope, element, attrs) {
                var handleFiles = $parse(attrs.snPasteImageHandler);
                element.bind("paste", function(e) {
                    e = e.originalEvent || e;
                    var item = e.clipboardData.items[0];
                    if (!item.kind)
                        return;
                    if (item.kind !== "file")
                        return;
                    var file = item.getAsFile();
                    file.name = "Pasted File - " + new Date();
                    handleFiles(scope, {
                        file: file
                    });
                    e.preventDefault();
                    e.stopPropagation();
                });
            }
        };
    });;
    /*! RESOURCE: /scripts/angularjs-1.4/sn/common/attachments/directive.snAttachmentList.js */
    angular.module('sn.common.attachments').directive('snAttachmentList', function(getTemplateUrl, snAttachmentHandler, $rootScope, $window, $timeout, $q) {
            'use strict';
            return {
                restrict: 'E',
                replace: true,
                templateUrl: getTemplateUrl("sn_attachment_list.xml"),
                scope: {
                    tableName: "=?",
                    sysID: "=?sysId",
                    attachmentList: "=?",
                    uploadFileFn: "&",
                    deleteFileFn: "=?",
                    canEdit: "=?",
                    canRemove: "=?",
                    canAdd: "=?",
                    canDownload: "=?",
                    showHeader: "=?",
                    clickImageFn: "&?",
                    confirmDelete: "=?"
                },
                controller: function($scope) {
                    $scope.canEdit = $scope.canEdit || false;
                    $scope.canDownload = $scope.canDownload || false;
                    $scope.canRemove = $scope.canRemove || false;
                    $scope.canAdd = $scope.canAdd || false;
                    $scope.showHeader = $scope.showHeader || false;
                    $scope.clickImageFn = $scope.clickImageFn || function() {};
                    $scope.confirmDelete = $scope.confirmDelete || false;
                    $scope.filesInProgress = {};
                    $scope.attachmentToDelete = null;
    
                    function refreshResources() {
                        var handler = snAttachmentHandler.create($scope.tableName, $scope.sysID);
                        handler.getAttachments().then(function(files) {
                            $scope.attachmentList = files;
                        });
                    }
                    if (!$scope.attachmentList) {
                        $scope.attachmentList = [];
                        refreshResources();
                    }
                    $scope.$on('attachments_list.update', function(e, tableName, sysID) {
                        if (tableName === $scope.tableName && sysID === $scope.sysID) {
                            refreshResources();
                        }
                    });
    
                    function removeFromFileProgress(fileName) {
                        delete $scope.filesInProgress[fileName];
                    }
    
                    function updateFileProgress(file) {
                        if (!$scope.filesInProgress[file.name])
                            $scope.filesInProgress[file.name] = file;
                    }
                    $scope.$on('attachments_list.upload.progress', function(e, file) {
                        updateFileProgress(file);
                    });
                    $scope.$on('attachments_list.upload.success', function(e, file) {
                        removeFromFileProgress(file.name);
                    });
                    $scope.attachFiles = function(files) {
                        if ($scope.tableName && $scope.sysID) {
                            var handler = snAttachmentHandler.create($scope.tableName, $scope.sysID);
                            var promises = [];
                            files.forEach(function(file) {
                                var promise = handler.uploadAttachment(file, null, {
                                    progress: function(e) {
                                        var file = e.config.file;
                                        file.progress = 100.0 * event.loaded / event.total;
                                        updateFileProgress(file);
                                    },
                                    success: function(data) {
                                        removeFromFileProgress(data.file_name);
                                    }
                                });
                                promises.push(promise);
                            });
                            $q.all(promises).then(function() {
                                refreshResources();
                            });
                        } else {
                            if ($scope.uploadFileFn)
                                $scope.uploadFileFn({
                                    files: files
                                });
                        }
                    };
                    $scope.getProgressStyle = function(fileName) {
                        return {
                            'width': $scope.filesInProgress[fileName].progress + '%'
                        };
                    };
                    $scope.openSelector = function($event) {
                        $event.stopPropagation();
                        var target = angular.element($event.currentTarget);
                        $timeout(function() {
                            target.parent().find('input').click();
                        });
                    };
                    $scope.confirmDeleteAttachment = function(attachment) {
                        $scope.attachmentToDelete = attachment;
                        $scope.$broadcast('dialog.confirm-delete.show');
                    };
                    $scope.deleteAttachment = function() {
                        snAttachmentHandler.deleteAttachment($scope.attachmentToDelete.sys_id).then(function() {
                            var index = $scope.attachmentList.indexOf($scope.attachmentToDelete);
                            $scope.attachmentList.splice(index, 1);
                        });
                    };
                }
            };
        })
        .directive('snAttachmentListItem', function(getTemplateUrl, snAttachmentHandler, $rootScope, $window, $timeout, $parse) {
            'use strict';
            return {
                restrict: "E",
                replace: true,
                templateUrl: getTemplateUrl("sn_attachment_list_item.xml"),
                link: function(scope, element, attrs) {
                    function translateAttachment(att) {
                        return {
                            content_type: att.content_type,
                            file_name: att.file_name,
                            image: (att.thumbSrc !== undefined),
                            size_bytes: att.size,
                            sys_created_by: "",
                            sys_created_on: "",
                            sys_id: att.sys_id,
                            thumb_src: att.thumbSrc
                        };
                    }
                    scope.attachment = ($parse(attrs.attachment.size_bytes)) ?
                        scope.$eval(attrs.attachment) :
                        translateAttachment(attrs.attachment);
                    var fileNameView = element.find('.sn-widget-list-title_view');
                    var fileNameEdit = element.find('.sn-widget-list-title_edit');
    
                    function editFileName() {
                        fileNameView.hide();
                        fileNameEdit.show();
                        element.find('.edit-text-input').focus();
                    }
    
                    function viewFileName() {
                        fileNameView.show();
                        fileNameEdit.hide();
                    }
                    viewFileName();
                    scope.editModeToggle = function($event) {
                        $event.preventDefault();
                        $event.stopPropagation();
                        scope.editMode = !scope.editMode;
                        if (scope.editMode)
                            editFileName();
                        else
                            viewFileName();
                    };
                    scope.updateName = function() {
                        scope.editMode = false;
                        viewFileName();
                        snAttachmentHandler.renameAttachment(scope.attachment.sys_id, scope.attachment.file_name);
                    };
                },
                controller: function($scope, snCustomEvent) {
                    $scope.editMode = false;
                    $scope.removeAttachment = function(attachment, index) {
                        if ($scope.deleteFileFn !== undefined && $scope.deleteFileFn instanceof Function) {
                            $scope.deleteFileFn.apply(null, arguments);
                            return;
                        }
                        if ($scope.confirmDelete) {
                            $scope.confirmDeleteAttachment($scope.attachment);
                            return;
                        }
                        snAttachmentHandler.deleteAttachment($scope.attachment.sys_id).then(function() {
                            $scope.attachmentList.splice($scope.$index, 1);
                        });
                    };
                    var contentTypeMap = {
                        "application/pdf": "icon-document-pdf",
                        "text/plain": "icon-document-txt",
                        "application/zip": "icon-document-zip",
                        "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "icon-document-doc",
                        "application/vnd.openxmlformats-officedocument.presentationml.presentation": "icon-document-ppt",
                        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "icon-document-xls",
                        "application/vnd.ms-powerpoint": "icon-document-ppt"
                    };
                    $scope.getDocumentType = function(contentType) {
                        return contentTypeMap[contentType] || "icon-document";
                    };
                    $scope.handleAttachmentClick = function(event) {
                        if (event.keyCode === 9)
                            return;
                        if ($scope.editMode)
                            return;
                        if (!$scope.attachment)
                            return;
                        if ($scope.attachment.image)
                            openImageInLightBox(event);
                        else
                            downloadAttachment();
                    };
    
                    function downloadAttachment() {
                        if (!$scope.attachment.sys_id)
                            return;
                        $window.location.href = 'sys_attachment.do?sys_id=' + $scope.attachment.sys_id;
                    }
    
                    function openImageInLightBox(event) {
                        if (!$scope.attachment.size)
                            $scope.attachment.size = $scope.getSize($scope.attachment.size_bytes, 2);
                        $scope.clickImageFn({
                            file: $scope.attachment
                        });
                        snCustomEvent.fire('sn.attachment.preview', event, $scope.attachment);
                    }
                    $scope.getSize = function(bytes, precision) {
                        if (typeof bytes === 'string' && bytes.slice(-1) === 'B')
                            return bytes;
                        var kb = 1024;
                        var mb = kb * 1024;
                        var gb = mb * 1024;
                        if ((bytes >= 0) && (bytes < kb))
                            return bytes + ' B';
                        else if ((bytes >= kb) && (bytes < mb))
                            return (bytes / kb).toFixed(precision) + ' KB';
                        else if ((bytes >= mb) && (bytes < gb))
                            return (bytes / mb).toFixed(precision) + ' MB';
                        else if (bytes >= gb)
                            return (bytes / gb).toFixed(precision) + ' GB';
                        else
                            return bytes + ' B';
                    }
                }
            };
        });;;
    /*! RESOURCE: /scripts/bootstrap_336.js */
    if (typeof jQuery === 'undefined') {
        throw new Error('Bootstrap\'s JavaScript requires jQuery')
    } +
    function($) {
        'use strict';
        var version = $.fn.jquery.split(' ')[0].split('.')
        if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 2)) {
            throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3')
        }
    }(jQuery); +
    function($) {
        'use strict';
    
        function transitionEnd() {
            var el = document.createElement('bootstrap')
            var transEndEventNames = {
                WebkitTransition: 'webkitTransitionEnd',
                MozTransition: 'transitionend',
                OTransition: 'oTransitionEnd otransitionend',
                transition: 'transitionend'
            }
            for (var name in transEndEventNames) {
                if (el.style[name] !== undefined) {
                    return {
                        end: transEndEventNames[name]
                    }
                }
            }
            return false
        }
        $.fn.emulateTransitionEnd = function(duration) {
            var called = false
            var $el = this
            $(this).one('bsTransitionEnd', function() {
                called = true
            })
            var callback = function() {
                if (!called) $($el).trigger($.support.transition.end)
            }
            setTimeout(callback, duration)
            return this
        }
        $(function() {
            $.support.transition = transitionEnd()
            if (!$.support.transition) return
            $.event.special.bsTransitionEnd = {
                bindType: $.support.transition.end,
                delegateType: $.support.transition.end,
                handle: function(e) {
                    if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
                }
            }
        })
    }(jQuery); +
    function($) {
        'use strict';
        var dismiss = '[data-dismiss="alert"]'
        var Alert = function(el) {
            $(el).on('click', dismiss, this.close)
        }
        Alert.VERSION = '3.3.6'
        Alert.TRANSITION_DURATION = 150
        Alert.prototype.close = function(e) {
            var $this = $(this)
            var selector = $this.attr('data-target')
            if (!selector) {
                selector = $this.attr('href')
                selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '')
            }
            var $parent = $(selector)
            if (e) e.preventDefault()
            if (!$parent.length) {
                $parent = $this.closest('.alert')
            }
            $parent.trigger(e = $.Event('close.bs.alert'))
            if (e.isDefaultPrevented()) return
            $parent.removeClass('in')
    
            function removeElement() {
                $parent.detach().trigger('closed.bs.alert').remove()
            }
            $.support.transition && $parent.hasClass('fade') ?
                $parent
                .one('bsTransitionEnd', removeElement)
                .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
                removeElement()
        }
    
        function Plugin(option) {
            return this.each(function() {
                var $this = $(this)
                var data = $this.data('bs.alert')
                if (!data) $this.data('bs.alert', (data = new Alert(this)))
                if (typeof option == 'string') data[option].call($this)
            })
        }
        var old = $.fn.alert
        $.fn.alert = Plugin
        $.fn.alert.Constructor = Alert
        $.fn.alert.noConflict = function() {
            $.fn.alert = old
            return this
        }
        $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
    }(jQuery); +
    function($) {
        'use strict';
        var Button = function(element, options) {
            this.$element = $(element)
            this.options = $.extend({}, Button.DEFAULTS, options)
            this.isLoading = false
        }
        Button.VERSION = '3.3.6'
        Button.DEFAULTS = {
            loadingText: 'loading...'
        }
        Button.prototype.setState = function(state) {
            var d = 'disabled'
            var $el = this.$element
            var val = $el.is('input') ? 'val' : 'html'
            var data = $el.data()
            state += 'Text'
            if (data.resetText == null) $el.data('resetText', $el[val]())
            setTimeout($.proxy(function() {
                $el[val](data[state] == null ? this.options[state] : data[state])
                if (state == 'loadingText') {
                    this.isLoading = true
                    $el.addClass(d).attr(d, d)
                } else if (this.isLoading) {
                    this.isLoading = false
                    $el.removeClass(d).removeAttr(d)
                }
            }, this), 0)
        }
        Button.prototype.toggle = function() {
            var changed = true
            var $parent = this.$element.closest('[data-toggle="buttons"]')
            if ($parent.length) {
                var $input = this.$element.find('input')
                if ($input.prop('type') == 'radio') {
                    if ($input.prop('checked')) changed = false
                    $parent.find('.active').removeClass('active')
                    this.$element.addClass('active')
                } else if ($input.prop('type') == 'checkbox') {
                    if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
                    this.$element.toggleClass('active')
                }
                $input.prop('checked', this.$element.hasClass('active'))
                if (changed) $input.trigger('change')
            } else {
                this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
                this.$element.toggleClass('active')
            }
        }
    
        function Plugin(option) {
            return this.each(function() {
                var $this = $(this)
                var data = $this.data('bs.button')
                var options = typeof option == 'object' && option
                if (!data) $this.data('bs.button', (data = new Button(this, options)))
                if (option == 'toggle') data.toggle()
                else if (option) data.setState(option)
            })
        }
        var old = $.fn.button
        $.fn.button = Plugin
        $.fn.button.Constructor = Button
        $.fn.button.noConflict = function() {
            $.fn.button = old
            return this
        }
        $(document)
            .on('click.bs.button.data-api', '[data-toggle^="button"]', function(e) {
                var $btn = $(e.target)
                if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
                Plugin.call($btn, 'toggle')
                if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault()
            })
            .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function(e) {
                $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
            })
    }(jQuery); +
    function($) {
        'use strict';
        var Carousel = function(element, options) {
            this.$element = $(element)
            this.$indicators = this.$element.find('.carousel-indicators')
            this.options = options
            this.paused = null
            this.sliding = null
            this.interval = null
            this.$active = null
            this.$items = null
            this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
            this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
                .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
                .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
        }
        Carousel.VERSION = '3.3.6'
        Carousel.TRANSITION_DURATION = 600
        Carousel.DEFAULTS = {
            interval: 5000,
            pause: 'hover',
            wrap: true,
            keyboard: true
        }
        Carousel.prototype.keydown = function(e) {
            if (/input|textarea/i.test(e.target.tagName)) return
            switch (e.which) {
                case 37:
                    this.prev();
                    break
                case 39:
                    this.next();
                    break
                default:
                    return
            }
            e.preventDefault()
        }
        Carousel.prototype.cycle = function(e) {
            e || (this.paused = false)
            this.interval && clearInterval(this.interval)
            this.options.interval &&
                !this.paused &&
                (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
            return this
        }
        Carousel.prototype.getItemIndex = function(item) {
            this.$items = item.parent().children('.item')
            return this.$items.index(item || this.$active)
        }
        Carousel.prototype.getItemForDirection = function(direction, active) {
            var activeIndex = this.getItemIndex(active)
            var willWrap = (direction == 'prev' && activeIndex === 0) ||
                (direction == 'next' && activeIndex == (this.$items.length - 1))
            if (willWrap && !this.options.wrap) return active
            var delta = direction == 'prev' ? -1 : 1
            var itemIndex = (activeIndex + delta) % this.$items.length
            return this.$items.eq(itemIndex)
        }
        Carousel.prototype.to = function(pos) {
            var that = this
            var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
            if (pos > (this.$items.length - 1) || pos < 0) return
            if (this.sliding) return this.$element.one('slid.bs.carousel', function() {
                that.to(pos)
            })
            if (activeIndex == pos) return this.pause().cycle()
            return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
        }
        Carousel.prototype.pause = function(e) {
            e || (this.paused = true)
            if (this.$element.find('.next, .prev').length && $.support.transition) {
                this.$element.trigger($.support.transition.end)
                this.cycle(true)
            }
            this.interval = clearInterval(this.interval)
            return this
        }
        Carousel.prototype.next = function() {
            if (this.sliding) return
            return this.slide('next')
        }
        Carousel.prototype.prev = function() {
            if (this.sliding) return
            return this.slide('prev')
        }
        Carousel.prototype.slide = function(type, next) {
            var $active = this.$element.find('.item.active')
            var $next = next || this.getItemForDirection(type, $active)
            var isCycling = this.interval
            var direction = type == 'next' ? 'left' : 'right'
            var that = this
            if ($next.hasClass('active')) return (this.sliding = false)
            var relatedTarget = $next[0]
            var slideEvent = $.Event('slide.bs.carousel', {
                relatedTarget: relatedTarget,
                direction: direction
            })
            this.$element.trigger(slideEvent)
            if (slideEvent.isDefaultPrevented()) return
            this.sliding = true
            isCycling && this.pause()
            if (this.$indicators.length) {
                this.$indicators.find('.active').removeClass('active')
                var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
                $nextIndicator && $nextIndicator.addClass('active')
            }
            var slidEvent = $.Event('slid.bs.carousel', {
                relatedTarget: relatedTarget,
                direction: direction
            })
            if ($.support.transition && this.$element.hasClass('slide')) {
                $next.addClass(type)
                $next[0].offsetWidth
                $active.addClass(direction)
                $next.addClass(direction)
                $active
                    .one('bsTransitionEnd', function() {
                        $next.removeClass([type, direction].join(' ')).addClass('active')
                        $active.removeClass(['active', direction].join(' '))
                        that.sliding = false
                        setTimeout(function() {
                            that.$element.trigger(slidEvent)
                        }, 0)
                    })
                    .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
            } else {
                $active.removeClass('active')
                $next.addClass('active')
                this.sliding = false
                this.$element.trigger(slidEvent)
            }
            isCycling && this.cycle()
            return this
        }
    
        function Plugin(option) {
            return this.each(function() {
                var $this = $(this)
                var data = $this.data('bs.carousel')
                var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
                var action = typeof option == 'string' ? option : options.slide
                if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
                if (typeof option == 'number') data.to(option)
                else if (action) data[action]()
                else if (options.interval) data.pause().cycle()
            })
        }
        var old = $.fn.carousel
        $.fn.carousel = Plugin
        $.fn.carousel.Constructor = Carousel
        $.fn.carousel.noConflict = function() {
            $.fn.carousel = old
            return this
        }
        var clickHandler = function(e) {
            var href
            var $this = $(this)
            var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, ''))
            if (!$target.hasClass('carousel')) return
            var options = $.extend({}, $target.data(), $this.data())
            var slideIndex = $this.attr('data-slide-to')
            if (slideIndex) options.interval = false
            Plugin.call($target, options)
            if (slideIndex) {
                $target.data('bs.carousel').to(slideIndex)
            }
            e.preventDefault()
        }
        $(document)
            .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
            .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
        $(window).on('load', function() {
            $('[data-ride="carousel"]').each(function() {
                var $carousel = $(this)
                Plugin.call($carousel, $carousel.data())
            })
        })
    }(jQuery); +
    function($) {
        'use strict';
        var Collapse = function(element, options) {
            this.$element = $(element)
            this.options = $.extend({}, Collapse.DEFAULTS, options)
            this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
                '[data-toggle="collapse"][data-target="#' + element.id + '"]')
            this.transitioning = null
            if (this.options.parent) {
                this.$parent = this.getParent()
            } else {
                this.addAriaAndCollapsedClass(this.$element, this.$trigger)
            }
            if (this.options.toggle) this.toggle()
        }
        Collapse.VERSION = '3.3.6'
        Collapse.TRANSITION_DURATION = 350
        Collapse.DEFAULTS = {
            toggle: true
        }
        Collapse.prototype.dimension = function() {
            var hasWidth = this.$element.hasClass('width')
            return hasWidth ? 'width' : 'height'
        }
        Collapse.prototype.show = function() {
            if (this.transitioning || this.$element.hasClass('in')) return
            var activesData
            var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
            if (actives && actives.length) {
                activesData = actives.data('bs.collapse')
                if (activesData && activesData.transitioning) return
            }
            var startEvent = $.Event('show.bs.collapse')
            this.$element.trigger(startEvent)
            if (startEvent.isDefaultPrevented()) return
            if (actives && actives.length) {
                Plugin.call(actives, 'hide')
                activesData || actives.data('bs.collapse', null)
            }
            var dimension = this.dimension()
            this.$element
                .removeClass('collapse')
                .addClass('collapsing')[dimension](0)
                .attr('aria-expanded', true)
            this.$trigger
                .removeClass('collapsed')
                .attr('aria-expanded', true)
            this.transitioning = 1
            var complete = function() {
                this.$element
                    .removeClass('collapsing')
                    .addClass('collapse in')[dimension]('')
                this.transitioning = 0
                this.$element
                    .trigger('shown.bs.collapse')
            }
            if (!$.support.transition) return complete.call(this)
            var scrollSize = $.camelCase(['scroll', dimension].join('-'))
            this.$element
                .one('bsTransitionEnd', $.proxy(complete, this))
                .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
        }
        Collapse.prototype.hide = function() {
            if (this.transitioning || !this.$element.hasClass('in')) return
            var startEvent = $.Event('hide.bs.collapse')
            this.$element.trigger(startEvent)
            if (startEvent.isDefaultPrevented()) return
            var dimension = this.dimension()
            this.$element[dimension](this.$element[dimension]())[0].offsetHeight
            this.$element
                .addClass('collapsing')
                .removeClass('collapse in')
                .attr('aria-expanded', false)
            this.$trigger
                .addClass('collapsed')
                .attr('aria-expanded', false)
            this.transitioning = 1
            var complete = function() {
                this.transitioning = 0
                this.$element
                    .removeClass('collapsing')
                    .addClass('collapse')
                    .trigger('hidden.bs.collapse')
            }
            if (!$.support.transition) return complete.call(this)
            this.$element[dimension](0)
                .one('bsTransitionEnd', $.proxy(complete, this))
                .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
        }
        Collapse.prototype.toggle = function() {
            this[this.$element.hasClass('in') ? 'hide' : 'show']()
        }
        Collapse.prototype.getParent = function() {
            return $(this.options.parent)
                .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
                .each($.proxy(function(i, element) {
                    var $element = $(element)
                    this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
                }, this))
                .end()
        }
        Collapse.prototype.addAriaAndCollapsedClass = function($element, $trigger) {
            var isOpen = $element.hasClass('in')
            $element.attr('aria-expanded', isOpen)
            $trigger
                .toggleClass('collapsed', !isOpen)
                .attr('aria-expanded', isOpen)
        }
    
        function getTargetFromTrigger($trigger) {
            var href
            var target = $trigger.attr('data-target') ||
                (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')
            return $(target)
        }
    
        function Plugin(option) {
            return this.each(function() {
                var $this = $(this)
                var data = $this.data('bs.collapse')
                var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
                if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
                if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
                if (typeof option == 'string') data[option]()
            })
        }
        var old = $.fn.collapse
        $.fn.collapse = Plugin
        $.fn.collapse.Constructor = Collapse
        $.fn.collapse.noConflict = function() {
            $.fn.collapse = old
            return this
        }
        $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function(e) {
            var $this = $(this)
            if (!$this.attr('data-target')) e.preventDefault()
            var $target = getTargetFromTrigger($this)
            var data = $target.data('bs.collapse')
            var option = data ? 'toggle' : $this.data()
            Plugin.call($target, option)
        })
    }(jQuery); +
    function($) {
        'use strict';
        var backdrop = '.dropdown-backdrop'
        var toggle = '[data-toggle="dropdown"]'
        var Dropdown = function(element) {
            $(element).on('click.bs.dropdown', this.toggle)
        }
        Dropdown.VERSION = '3.3.6'
    
        function getParent($this) {
            var selector = $this.attr('data-target')
            if (!selector) {
                selector = $this.attr('href')
                selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '')
            }
            var $parent = selector && $(selector)
            return $parent && $parent.length ? $parent : $this.parent()
        }
    
        function clearMenus(e) {
            if (e && e.which === 3) return
            $(backdrop).remove()
            $(toggle).each(function() {
                var $this = $(this)
                var $parent = getParent($this)
                var relatedTarget = {
                    relatedTarget: this
                }
                if (!$parent.hasClass('open')) return
                if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
                $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
                if (e.isDefaultPrevented()) return
                $this.attr('aria-expanded', 'false')
                $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
            })
        }
        Dropdown.prototype.toggle = function(e) {
            var $this = $(this)
            if ($this.is('.disabled, :disabled')) return
            var $parent = getParent($this)
            var isActive = $parent.hasClass('open')
            clearMenus()
            if (!isActive) {
                if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
                    $(document.createElement('div'))
                        .addClass('dropdown-backdrop')
                        .insertAfter($(this))
                        .on('click', clearMenus)
                }
                var relatedTarget = {
                    relatedTarget: this
                }
                $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
                if (e.isDefaultPrevented()) return
                $this
                    .trigger('focus')
                    .attr('aria-expanded', 'true')
                $parent
                    .toggleClass('open')
                    .trigger($.Event('shown.bs.dropdown', relatedTarget))
            }
            return false
        }
        Dropdown.prototype.keydown = function(e) {
            if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
            var $this = $(this)
            e.preventDefault()
            e.stopPropagation()
            if ($this.is('.disabled, :disabled')) return
            var $parent = getParent($this)
            var isActive = $parent.hasClass('open')
            if (!isActive && e.which != 27 || isActive && e.which == 27) {
                if (e.which == 27) $parent.find(toggle).trigger('focus')
                return $this.trigger('click')
            }
            var desc = ' li:not(.disabled):visible a'
            var $items = $parent.find('.dropdown-menu' + desc)
            if (!$items.length) return
            var index = $items.index(e.target)
            if (e.which == 38 && index > 0) index--
                if (e.which == 40 && index < $items.length - 1) index++
                    if (!~index) index = 0
            $items.eq(index).trigger('focus')
        }
    
        function Plugin(option) {
            return this.each(function() {
                var $this = $(this)
                var data = $this.data('bs.dropdown')
                if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
                if (typeof option == 'string') data[option].call($this)
            })
        }
        var old = $.fn.dropdown
        $.fn.dropdown = Plugin
        $.fn.dropdown.Constructor = Dropdown
        $.fn.dropdown.noConflict = function() {
            $.fn.dropdown = old
            return this
        }
        $(document)
            .on('click.bs.dropdown.data-api', clearMenus)
            .on('click.bs.dropdown.data-api', '.dropdown form', function(e) {
                e.stopPropagation()
            })
            .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
            .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
            .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
    }(jQuery); +
    function($) {
        'use strict';
        var Modal = function(element, options) {
            this.options = options
            this.$body = $(document.body)
            this.$element = $(element)
            this.$dialog = this.$element.find('.modal-dialog')
            this.$backdrop = null
            this.isShown = null
            this.originalBodyPad = null
            this.scrollbarWidth = 0
            this.ignoreBackdropClick = false
            if (this.options.remote) {
                this.$element
                    .find('.modal-content')
                    .load(this.options.remote, $.proxy(function() {
                        this.$element.trigger('loaded.bs.modal')
                    }, this))
            }
        }
        Modal.VERSION = '3.3.6'
        Modal.TRANSITION_DURATION = 300
        Modal.BACKDROP_TRANSITION_DURATION = 150
        Modal.DEFAULTS = {
            backdrop: true,
            keyboard: true,
            show: true
        }
        Modal.prototype.toggle = function(_relatedTarget) {
            return this.isShown ? this.hide() : this.show(_relatedTarget)
        }
        Modal.prototype.show = function(_relatedTarget) {
            var that = this
            var e = $.Event('show.bs.modal', {
                relatedTarget: _relatedTarget
            })
            this.$element.trigger(e)
            if (this.isShown || e.isDefaultPrevented()) return
            this.isShown = true
            this.checkScrollbar()
            this.setScrollbar()
            this.$body.addClass('modal-open')
            this.escape()
            this.resize()
            this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
            this.$dialog.on('mousedown.dismiss.bs.modal', function() {
                that.$element.one('mouseup.dismiss.bs.modal', function(e) {
                    if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
                })
            })
            this.backdrop(function() {
                var transition = $.support.transition && that.$element.hasClass('fade')
                if (!that.$element.parent().length) {
                    that.$element.appendTo(that.$body)
                }
                that.$element
                    .show()
                    .scrollTop(0)
                that.adjustDialog()
                if (transition) {
                    that.$element[0].offsetWidth
                }
                that.$element.addClass('in')
                that.enforceFocus()
                var e = $.Event('shown.bs.modal', {
                    relatedTarget: _relatedTarget
                })
                transition ?
                    that.$dialog
                    .one('bsTransitionEnd', function() {
                        that.$element.trigger('focus').trigger(e)
                    })
                    .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
                    that.$element.trigger('focus').trigger(e)
            })
        }
        Modal.prototype.hide = function(e) {
            if (e) e.preventDefault()
            e = $.Event('hide.bs.modal')
            this.$element.trigger(e)
            if (!this.isShown || e.isDefaultPrevented()) return
            this.isShown = false
            this.escape()
            this.resize()
            $(document).off('focusin.bs.modal')
            this.$element
                .removeClass('in')
                .off('click.dismiss.bs.modal')
                .off('mouseup.dismiss.bs.modal')
            this.$dialog.off('mousedown.dismiss.bs.modal')
            $.support.transition && this.$element.hasClass('fade') ?
                this.$element
                .one('bsTransitionEnd', $.proxy(this.hideModal, this))
                .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
                this.hideModal()
        }
        Modal.prototype.enforceFocus = function() {
            $(document)
                .off('focusin.bs.modal')
                .on('focusin.bs.modal', $.proxy(function(e) {
                    if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
                        this.$element.trigger('focus')
                    }
                }, this))
        }
        Modal.prototype.escape = function() {
            if (this.isShown && this.options.keyboard) {
                this.$element.on('keydown.dismiss.bs.modal', $.proxy(function(e) {
                    e.which == 27 && this.hide()
                }, this))
            } else if (!this.isShown) {
                this.$element.off('keydown.dismiss.bs.modal')
            }
        }
        Modal.prototype.resize = function() {
            if (this.isShown) {
                $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
            } else {
                $(window).off('resize.bs.modal')
            }
        }
        Modal.prototype.hideModal = function() {
            var that = this
            this.$element.hide()
            this.backdrop(function() {
                that.$body.removeClass('modal-open')
                that.resetAdjustments()
                that.resetScrollbar()
                that.$element.trigger('hidden.bs.modal')
            })
        }
        Modal.prototype.removeBackdrop = function() {
            this.$backdrop && this.$backdrop.remove()
            this.$backdrop = null
        }
        Modal.prototype.backdrop = function(callback) {
            var that = this
            var animate = this.$element.hasClass('fade') ? 'fade' : ''
            if (this.isShown && this.options.backdrop) {
                var doAnimate = $.support.transition && animate
                this.$backdrop = $(document.createElement('div'))
                    .addClass('modal-backdrop ' + animate)
                    .appendTo(this.$body)
                this.$element.on('click.dismiss.bs.modal', $.proxy(function(e) {
                    if (this.ignoreBackdropClick) {
                        this.ignoreBackdropClick = false
                        return
                    }
                    if (e.target !== e.currentTarget) return
                    this.options.backdrop == 'static' ?
                        this.$element[0].focus() :
                        this.hide()
                }, this))
                if (doAnimate) this.$backdrop[0].offsetWidth
                this.$backdrop.addClass('in')
                if (!callback) return
                doAnimate ?
                    this.$backdrop
                    .one('bsTransitionEnd', callback)
                    .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
                    callback()
            } else if (!this.isShown && this.$backdrop) {
                this.$backdrop.removeClass('in')
                var callbackRemove = function() {
                    that.removeBackdrop()
                    callback && callback()
                }
                $.support.transition && this.$element.hasClass('fade') ?
                    this.$backdrop
                    .one('bsTransitionEnd', callbackRemove)
                    .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
                    callbackRemove()
            } else if (callback) {
                callback()
            }
        }
        Modal.prototype.handleUpdate = function() {
            this.adjustDialog()
        }
        Modal.prototype.adjustDialog = function() {
            var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
            this.$element.css({
                paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
                paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
            })
        }
        Modal.prototype.resetAdjustments = function() {
            this.$element.css({
                paddingLeft: '',
                paddingRight: ''
            })
        }
        Modal.prototype.checkScrollbar = function() {
            var fullWindowWidth = window.innerWidth
            if (!fullWindowWidth) {
                var documentElementRect = document.documentElement.getBoundingClientRect()
                fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
            }
            this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
            this.scrollbarWidth = this.measureScrollbar()
        }
        Modal.prototype.setScrollbar = function() {
            var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
            this.originalBodyPad = document.body.style.paddingRight || ''
            if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
        }
        Modal.prototype.resetScrollbar = function() {
            this.$body.css('padding-right', this.originalBodyPad)
        }
        Modal.prototype.measureScrollbar = function() {
            var scrollDiv = document.createElement('div')
            scrollDiv.className = 'modal-scrollbar-measure'
            this.$body.append(scrollDiv)
            var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
            this.$body[0].removeChild(scrollDiv)
            return scrollbarWidth
        }
    
        function Plugin(option, _relatedTarget) {
            return this.each(function() {
                var $this = $(this)
                var data = $this.data('bs.modal')
                var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
                if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
                if (typeof option == 'string') data[option](_relatedTarget)
                else if (options.show) data.show(_relatedTarget)
            })
        }
        var old = $.fn.modal
        $.fn.modal = Plugin
        $.fn.modal.Constructor = Modal
        $.fn.modal.noConflict = function() {
            $.fn.modal = old
            return this
        }
        $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function(e) {
            var $this = $(this)
            var href = $this.attr('href')
            var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, '')))
            var option = $target.data('bs.modal') ? 'toggle' : $.extend({
                remote: !/#/.test(href) && href
            }, $target.data(), $this.data())
            if ($this.is('a')) e.preventDefault()
            $target.one('show.bs.modal', function(showEvent) {
                if (showEvent.isDefaultPrevented()) return
                $target.one('hidden.bs.modal', function() {
                    $this.is(':visible') && $this.trigger('focus')
                })
            })
            Plugin.call($target, option, this)
        })
    }(jQuery); +
    function($) {
        'use strict';
        var Tooltip = function(element, options) {
            this.type = null
            this.options = null
            this.enabled = null
            this.timeout = null
            this.hoverState = null
            this.$element = null
            this.inState = null
            this.init('tooltip', element, options)
        }
        Tooltip.VERSION = '3.3.6'
        Tooltip.TRANSITION_DURATION = 150
        Tooltip.DEFAULTS = {
            animation: true,
            placement: 'top',
            selector: false,
            template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
            trigger: 'hover focus',
            title: '',
            delay: 0,
            html: false,
            container: false,
            viewport: {
                selector: 'body',
                padding: 0
            }
        }
        Tooltip.prototype.init = function(type, element, options) {
            this.enabled = true
            this.type = type
            this.$element = $(element)
            this.options = this.getOptions(options)
            this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
            this.inState = {
                click: false,
                hover: false,
                focus: false
            }
            if (this.$element[0] instanceof document.constructor && !this.options.selector) {
                throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
            }
            var triggers = this.options.trigger.split(' ')
            for (var i = triggers.length; i--;) {
                var trigger = triggers[i]
                if (trigger == 'click') {
                    this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
                } else if (trigger != 'manual') {
                    var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
                    var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
                    this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
                    this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
                }
            }
            this.options.selector ?
                (this._options = $.extend({}, this.options, {
                    trigger: 'manual',
                    selector: ''
                })) :
                this.fixTitle()
        }
        Tooltip.prototype.getDefaults = function() {
            return Tooltip.DEFAULTS
        }
        Tooltip.prototype.getOptions = function(options) {
            options = $.extend({}, this.getDefaults(), this.$element.data(), options)
            if (options.delay && typeof options.delay == 'number') {
                options.delay = {
                    show: options.delay,
                    hide: options.delay
                }
            }
            return options
        }
        Tooltip.prototype.getDelegateOptions = function() {
            var options = {}
            var defaults = this.getDefaults()
            this._options && $.each(this._options, function(key, value) {
                if (defaults[key] != value) options[key] = value
            })
            return options
        }
        Tooltip.prototype.enter = function(obj) {
            var self = obj instanceof this.constructor ?
                obj : $(obj.currentTarget).data('bs.' + this.type)
            if (!self) {
                self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
                $(obj.currentTarget).data('bs.' + this.type, self)
            }
            if (obj instanceof $.Event) {
                self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
            }
            if (self.tip().hasClass('in') || self.hoverState == 'in') {
                self.hoverState = 'in'
                return
            }
            clearTimeout(self.timeout)
            self.hoverState = 'in'
            if (!self.options.delay || !self.options.delay.show) return self.show()
            self.timeout = setTimeout(function() {
                if (self.hoverState == 'in') self.show()
            }, self.options.delay.show)
        }
        Tooltip.prototype.isInStateTrue = function() {
            for (var key in this.inState) {
                if (this.inState[key]) return true
            }
            return false
        }
        Tooltip.prototype.leave = function(obj) {
            var self = obj instanceof this.constructor ?
                obj : $(obj.currentTarget).data('bs.' + this.type)
            if (!self) {
                self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
                $(obj.currentTarget).data('bs.' + this.type, self)
            }
            if (obj instanceof $.Event) {
                self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
            }
            if (self.isInStateTrue()) return
            clearTimeout(self.timeout)
            self.hoverState = 'out'
            if (!self.options.delay || !self.options.delay.hide) return self.hide()
            self.timeout = setTimeout(function() {
                if (self.hoverState == 'out') self.hide()
            }, self.options.delay.hide)
        }
        Tooltip.prototype.show = function() {
            var e = $.Event('show.bs.' + this.type)
            if (this.hasContent() && this.enabled) {
                this.$element.trigger(e)
                var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
                if (e.isDefaultPrevented() || !inDom) return
                var that = this
                var $tip = this.tip()
                var tipId = this.getUID(this.type)
                this.setContent()
                $tip.attr('id', tipId)
                this.$element.attr('aria-describedby', tipId)
                if (this.options.animation) $tip.addClass('fade')
                var placement = typeof this.options.placement == 'function' ?
                    this.options.placement.call(this, $tip[0], this.$element[0]) :
                    this.options.placement
                var autoToken = /\s?auto?\s?/i
                var autoPlace = autoToken.test(placement)
                if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
                $tip
                    .detach()
                    .css({
                        top: 0,
                        left: 0,
                        display: 'block'
                    })
                    .addClass(placement)
                    .data('bs.' + this.type, this)
                this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
                this.$element.trigger('inserted.bs.' + this.type)
                var pos = this.getPosition()
                var actualWidth = $tip[0].offsetWidth
                var actualHeight = $tip[0].offsetHeight
                if (autoPlace) {
                    var orgPlacement = placement
                    var viewportDim = this.getPosition(this.$viewport)
                    placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
                        placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
                        placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
                        placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
                        placement
                    $tip
                        .removeClass(orgPlacement)
                        .addClass(placement)
                }
                var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
                this.applyPlacement(calculatedOffset, placement)
                var complete = function() {
                    var prevHoverState = that.hoverState
                    that.$element.trigger('shown.bs.' + that.type)
                    that.hoverState = null
                    if (prevHoverState == 'out') that.leave(that)
                }
                $.support.transition && this.$tip.hasClass('fade') ?
                    $tip
                    .one('bsTransitionEnd', complete)
                    .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
                    complete()
            }
        }
        Tooltip.prototype.applyPlacement = function(offset, placement) {
            var $tip = this.tip()
            var width = $tip[0].offsetWidth
            var height = $tip[0].offsetHeight
            var marginTop = parseInt($tip.css('margin-top'), 10)
            var marginLeft = parseInt($tip.css('margin-left'), 10)
            if (isNaN(marginTop)) marginTop = 0
            if (isNaN(marginLeft)) marginLeft = 0
            offset.top += marginTop
            offset.left += marginLeft
            $.offset.setOffset($tip[0], $.extend({
                using: function(props) {
                    $tip.css({
                        top: Math.round(props.top),
                        left: Math.round(props.left)
                    })
                }
            }, offset), 0)
            $tip.addClass('in')
            var actualWidth = $tip[0].offsetWidth
            var actualHeight = $tip[0].offsetHeight
            if (placement == 'top' && actualHeight != height) {
                offset.top = offset.top + height - actualHeight
            }
            var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
            if (delta.left) offset.left += delta.left
            else offset.top += delta.top
            var isVertical = /top|bottom/.test(placement)
            var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
            var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
            $tip.offset(offset)
            this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
        }
        Tooltip.prototype.replaceArrow = function(delta, dimension, isVertical) {
            this.arrow()
                .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
                .css(isVertical ? 'top' : 'left', '')
        }
        Tooltip.prototype.setContent = function() {
            var $tip = this.tip()
            var title = this.getTitle()
            $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
            $tip.removeClass('fade in top bottom left right')
        }
        Tooltip.prototype.hide = function(callback) {
            var that = this
            var $tip = $(this.$tip)
            var e = $.Event('hide.bs.' + this.type)
    
            function complete() {
                if (that.hoverState != 'in') $tip.detach()
                that.$element
                    .removeAttr('aria-describedby')
                    .trigger('hidden.bs.' + that.type)
                callback && callback()
            }
            this.$element.trigger(e)
            if (e.isDefaultPrevented()) return
            $tip.removeClass('in')
            $.support.transition && $tip.hasClass('fade') ?
                $tip
                .one('bsTransitionEnd', complete)
                .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
                complete()
            this.hoverState = null
            return this
        }
        Tooltip.prototype.fixTitle = function() {
            var $e = this.$element
            if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
                $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
            }
        }
        Tooltip.prototype.hasContent = function() {
            return this.getTitle()
        }
        Tooltip.prototype.getPosition = function($element) {
            $element = $element || this.$element
            var el = $element[0]
            var isBody = el.tagName == 'BODY'
            var elRect = el.getBoundingClientRect()
            if (elRect.width == null) {
                elRect = $.extend({}, elRect, {
                    width: elRect.right - elRect.left,
                    height: elRect.bottom - elRect.top
                })
            }
            var elOffset = isBody ? {
                top: 0,
                left: 0
            } : $element.offset()
            var scroll = {
                scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop()
            }
            var outerDims = isBody ? {
                width: $(window).width(),
                height: $(window).height()
            } : null
            return $.extend({}, elRect, scroll, outerDims, elOffset)
        }
        Tooltip.prototype.getCalculatedOffset = function(placement, pos, actualWidth, actualHeight) {
            return placement == 'bottom' ? {
                    top: pos.top + pos.height,
                    left: pos.left + pos.width / 2 - actualWidth / 2
                } :
                placement == 'top' ? {
                    top: pos.top - actualHeight,
                    left: pos.left + pos.width / 2 - actualWidth / 2
                } :
                placement == 'left' ? {
                    top: pos.top + pos.height / 2 - actualHeight / 2,
                    left: pos.left - actualWidth
                } : {
                    top: pos.top + pos.height / 2 - actualHeight / 2,
                    left: pos.left + pos.width
                }
        }
        Tooltip.prototype.getViewportAdjustedDelta = function(placement, pos, actualWidth, actualHeight) {
            var delta = {
                top: 0,
                left: 0
            }
            if (!this.$viewport) return delta
            var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
            var viewportDimensions = this.getPosition(this.$viewport)
            if (/right|left/.test(placement)) {
                var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
                var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
                if (topEdgeOffset < viewportDimensions.top) {
                    delta.top = viewportDimensions.top - topEdgeOffset
                } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) {
                    delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
                }
            } else {
                var leftEdgeOffset = pos.left - viewportPadding
                var rightEdgeOffset = pos.left + viewportPadding + actualWidth
                if (leftEdgeOffset < viewportDimensions.left) {
                    delta.left = viewportDimensions.left - leftEdgeOffset
                } else if (rightEdgeOffset > viewportDimensions.right) {
                    delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
                }
            }
            return delta
        }
        Tooltip.prototype.getTitle = function() {
            var title
            var $e = this.$element
            var o = this.options
            title = $e.attr('data-original-title') ||
                (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
            return title
        }
        Tooltip.prototype.getUID = function(prefix) {
            do prefix += ~~(Math.random() * 1000000)
            while (document.getElementById(prefix))
            return prefix
        }
        Tooltip.prototype.tip = function() {
            if (!this.$tip) {
                this.$tip = $(this.options.template)
                if (this.$tip.length != 1) {
                    throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
                }
            }
            return this.$tip
        }
        Tooltip.prototype.arrow = function() {
            return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
        }
        Tooltip.prototype.enable = function() {
            this.enabled = true
        }
        Tooltip.prototype.disable = function() {
            this.enabled = false
        }
        Tooltip.prototype.toggleEnabled = function() {
            this.enabled = !this.enabled
        }
        Tooltip.prototype.toggle = function(e) {
            var self = this
            if (e) {
                self = $(e.currentTarget).data('bs.' + this.type)
                if (!self) {
                    self = new this.constructor(e.currentTarget, this.getDelegateOptions())
                    $(e.currentTarget).data('bs.' + this.type, self)
                }
            }
            if (e) {
                self.inState.click = !self.inState.click
                if (self.isInStateTrue()) self.enter(self)
                else self.leave(self)
            } else {
                self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
            }
        }
        Tooltip.prototype.destroy = function() {
            var that = this
            clearTimeout(this.timeout)
            this.hide(function() {
                that.$element.off('.' + that.type).removeData('bs.' + that.type)
                if (that.$tip) {
                    that.$tip.detach()
                }
                that.$tip = null
                that.$arrow = null
                that.$viewport = null
            })
        }
    
        function Plugin(option) {
            return this.each(function() {
                var $this = $(this)
                var data = $this.data('bs.tooltip')
                var options = typeof option == 'object' && option
                if (!data && /destroy|hide/.test(option)) return
                if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
                if (typeof option == 'string') data[option]()
            })
        }
        var old = $.fn.tooltip
        $.fn.tooltip = Plugin
        $.fn.tooltip.Constructor = Tooltip
        $.fn.tooltip.noConflict = function() {
            $.fn.tooltip = old
            return this
        }
    }(jQuery); +
    function($) {
        'use strict';
        var Popover = function(element, options) {
            this.init('popover', element, options)
        }
        if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
        Popover.VERSION = '3.3.6'
        Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
            placement: 'right',
            trigger: 'click',
            content: '',
            template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
        })
        Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
        Popover.prototype.constructor = Popover
        Popover.prototype.getDefaults = function() {
            return Popover.DEFAULTS
        }
        Popover.prototype.setContent = function() {
            var $tip = this.tip()
            var title = this.getTitle()
            var content = this.getContent()
            $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
            $tip.find('.popover-content').children().detach().end()[
                this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
            ](content)
            $tip.removeClass('fade top bottom left right in')
            if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
        }
        Popover.prototype.hasContent = function() {
            return this.getTitle() || this.getContent()
        }
        Popover.prototype.getContent = function() {
            var $e = this.$element
            var o = this.options
            return $e.attr('data-content') ||
                (typeof o.content == 'function' ?
                    o.content.call($e[0]) :
                    o.content)
        }
        Popover.prototype.arrow = function() {
            return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
        }
    
        function Plugin(option) {
            return this.each(function() {
                var $this = $(this)
                var data = $this.data('bs.popover')
                var options = typeof option == 'object' && option
                if (!data && /destroy|hide/.test(option)) return
                if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
                if (typeof option == 'string') data[option]()
            })
        }
        var old = $.fn.popover
        $.fn.popover = Plugin
        $.fn.popover.Constructor = Popover
        $.fn.popover.noConflict = function() {
            $.fn.popover = old
            return this
        }
    }(jQuery); +
    function($) {
        'use strict';
    
        function ScrollSpy(element, options) {
            this.$body = $(document.body)
            this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
            this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
            this.selector = (this.options.target || '') + ' .nav li > a'
            this.offsets = []
            this.targets = []
            this.activeTarget = null
            this.scrollHeight = 0
            this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
            this.refresh()
            this.process()
        }
        ScrollSpy.VERSION = '3.3.6'
        ScrollSpy.DEFAULTS = {
            offset: 10
        }
        ScrollSpy.prototype.getScrollHeight = function() {
            return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
        }
        ScrollSpy.prototype.refresh = function() {
            var that = this
            var offsetMethod = 'offset'
            var offsetBase = 0
            this.offsets = []
            this.targets = []
            this.scrollHeight = this.getScrollHeight()
            if (!$.isWindow(this.$scrollElement[0])) {
                offsetMethod = 'position'
                offsetBase = this.$scrollElement.scrollTop()
            }
            this.$body
                .find(this.selector)
                .map(function() {
                    var $el = $(this)
                    var href = $el.data('target') || $el.attr('href')
                    var $href = /^#./.test(href) && $(href)
                    return ($href &&
                        $href.length &&
                        $href.is(':visible') &&
                        [
                            [$href[offsetMethod]().top + offsetBase, href]
                        ]) || null
                })
                .sort(function(a, b) {
                    return a[0] - b[0]
                })
                .each(function() {
                    that.offsets.push(this[0])
                    that.targets.push(this[1])
                })
        }
        ScrollSpy.prototype.process = function() {
            var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
            var scrollHeight = this.getScrollHeight()
            var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
            var offsets = this.offsets
            var targets = this.targets
            var activeTarget = this.activeTarget
            var i
            if (this.scrollHeight != scrollHeight) {
                this.refresh()
            }
            if (scrollTop >= maxScroll) {
                return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
            }
            if (activeTarget && scrollTop < offsets[0]) {
                this.activeTarget = null
                return this.clear()
            }
            for (i = offsets.length; i--;) {
                activeTarget != targets[i] &&
                    scrollTop >= offsets[i] &&
                    (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) &&
                    this.activate(targets[i])
            }
        }
        ScrollSpy.prototype.activate = function(target) {
            this.activeTarget = target
            this.clear()
            var selector = this.selector +
                '[data-target="' + target + '"],' +
                this.selector + '[href="' + target + '"]'
            var active = $(selector)
                .parents('li')
                .addClass('active')
            if (active.parent('.dropdown-menu').length) {
                active = active
                    .closest('li.dropdown')
                    .addClass('active')
            }
            active.trigger('activate.bs.scrollspy')
        }
        ScrollSpy.prototype.clear = function() {
            $(this.selector)
                .parentsUntil(this.options.target, '.active')
                .removeClass('active')
        }
    
        function Plugin(option) {
            return this.each(function() {
                var $this = $(this)
                var data = $this.data('bs.scrollspy')
                var options = typeof option == 'object' && option
                if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
                if (typeof option == 'string') data[option]()
            })
        }
        var old = $.fn.scrollspy
        $.fn.scrollspy = Plugin
        $.fn.scrollspy.Constructor = ScrollSpy
        $.fn.scrollspy.noConflict = function() {
            $.fn.scrollspy = old
            return this
        }
        $(window).on('load.bs.scrollspy.data-api', function() {
            $('[data-spy="scroll"]').each(function() {
                var $spy = $(this)
                Plugin.call($spy, $spy.data())
            })
        })
    }(jQuery); +
    function($) {
        'use strict';
        var Tab = function(element) {
            this.element = $(element)
        }
        Tab.VERSION = '3.3.6'
        Tab.TRANSITION_DURATION = 150
        Tab.prototype.show = function() {
            var $this = this.element
            var $ul = $this.closest('ul:not(.dropdown-menu)')
            var selector = $this.data('target')
            if (!selector) {
                selector = $this.attr('href')
                selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '')
            }
            if ($this.parent('li').hasClass('active')) return
            var $previous = $ul.find('.active:last a')
            var hideEvent = $.Event('hide.bs.tab', {
                relatedTarget: $this[0]
            })
            var showEvent = $.Event('show.bs.tab', {
                relatedTarget: $previous[0]
            })
            $previous.trigger(hideEvent)
            $this.trigger(showEvent)
            if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
            var $target = $(selector)
            this.activate($this.closest('li'), $ul)
            this.activate($target, $target.parent(), function() {
                $previous.trigger({
                    type: 'hidden.bs.tab',
                    relatedTarget: $this[0]
                })
                $this.trigger({
                    type: 'shown.bs.tab',
                    relatedTarget: $previous[0]
                })
            })
        }
        Tab.prototype.activate = function(element, container, callback) {
            var $active = container.find('> .active')
            var transition = callback &&
                $.support.transition &&
                ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
    
            function next() {
                $active
                    .removeClass('active')
                    .find('> .dropdown-menu > .active')
                    .removeClass('active')
                    .end()
                    .find('[data-toggle="tab"]')
                    .attr('aria-expanded', false)
                element
                    .addClass('active')
                    .find('[data-toggle="tab"]')
                    .attr('aria-expanded', true)
                if (transition) {
                    element[0].offsetWidth
                    element.addClass('in')
                } else {
                    element.removeClass('fade')
                }
                if (element.parent('.dropdown-menu').length) {
                    element
                        .closest('li.dropdown')
                        .addClass('active')
                        .end()
                        .find('[data-toggle="tab"]')
                        .attr('aria-expanded', true)
                }
                callback && callback()
            }
            $active.length && transition ?
                $active
                .one('bsTransitionEnd', next)
                .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
                next()
            $active.removeClass('in')
        }
    
        function Plugin(option) {
            return this.each(function() {
                var $this = $(this)
                var data = $this.data('bs.tab')
                if (!data) $this.data('bs.tab', (data = new Tab(this)))
                if (typeof option == 'string') data[option]()
            })
        }
        var old = $.fn.tab
        $.fn.tab = Plugin
        $.fn.tab.Constructor = Tab
        $.fn.tab.noConflict = function() {
            $.fn.tab = old
            return this
        }
        var clickHandler = function(e) {
            e.preventDefault()
            Plugin.call($(this), 'show')
        }
        $(document)
            .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
            .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
    }(jQuery); +
    function($) {
        'use strict';
        var Affix = function(element, options) {
            this.options = $.extend({}, Affix.DEFAULTS, options)
            this.$target = $(this.options.target)
                .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
                .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
            this.$element = $(element)
            this.affixed = null
            this.unpin = null
            this.pinnedOffset = null
            this.checkPosition()
        }
        Affix.VERSION = '3.3.6'
        Affix.RESET = 'affix affix-top affix-bottom'
        Affix.DEFAULTS = {
            offset: 0,
            target: window
        }
        Affix.prototype.getState = function(scrollHeight, height, offsetTop, offsetBottom) {
            var scrollTop = this.$target.scrollTop()
            var position = this.$element.offset()
            var targetHeight = this.$target.height()
            if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
            if (this.affixed == 'bottom') {
                if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
                return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
            }
            var initializing = this.affixed == null
            var colliderTop = initializing ? scrollTop : position.top
            var colliderHeight = initializing ? targetHeight : height
            if (offsetTop != null && scrollTop <= offsetTop) return 'top'
            if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
            return false
        }
        Affix.prototype.getPinnedOffset = function() {
            if (this.pinnedOffset) return this.pinnedOffset
            this.$element.removeClass(Affix.RESET).addClass('affix')
            var scrollTop = this.$target.scrollTop()
            var position = this.$element.offset()
            return (this.pinnedOffset = position.top - scrollTop)
        }
        Affix.prototype.checkPositionWithEventLoop = function() {
            setTimeout($.proxy(this.checkPosition, this), 1)
        }
        Affix.prototype.checkPosition = function() {
            if (!this.$element.is(':visible')) return
            var height = this.$element.height()
            var offset = this.options.offset
            var offsetTop = offset.top
            var offsetBottom = offset.bottom
            var scrollHeight = Math.max($(document).height(), $(document.body).height())
            if (typeof offset != 'object') offsetBottom = offsetTop = offset
            if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
            if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
            var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
            if (this.affixed != affix) {
                if (this.unpin != null) this.$element.css('top', '')
                var affixType = 'affix' + (affix ? '-' + affix : '')
                var e = $.Event(affixType + '.bs.affix')
                this.$element.trigger(e)
                if (e.isDefaultPrevented()) return
                this.affixed = affix
                this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
                this.$element
                    .removeClass(Affix.RESET)
                    .addClass(affixType)
                    .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
            }
            if (affix == 'bottom') {
                this.$element.offset({
                    top: scrollHeight - height - offsetBottom
                })
            }
        }
    
        function Plugin(option) {
            return this.each(function() {
                var $this = $(this)
                var data = $this.data('bs.affix')
                var options = typeof option == 'object' && option
                if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
                if (typeof option == 'string') data[option]()
            })
        }
        var old = $.fn.affix
        $.fn.affix = Plugin
        $.fn.affix.Constructor = Affix
        $.fn.affix.noConflict = function() {
            $.fn.affix = old
            return this
        }
        $(window).on('load', function() {
            $('[data-spy="affix"]').each(function() {
                var $spy = $(this)
                var data = $spy.data()
                data.offset = data.offset || {}
                if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
                if (data.offsetTop != null) data.offset.top = data.offsetTop
                Plugin.call($spy, data)
            })
        })
    }(jQuery);;
    /*! RESOURCE: /scripts/iconset-fontawesome-4.2.0.js */
    ;
    (function($) {
        $.iconset_fontawesome = {
            iconClass: 'fa',
            iconClassFix: 'fa-',
            icons: [
                '',
                'adjust',
                'anchor',
                'archive',
                'area-chart',
                'arrows',
                'arrows-h',
                'arrows-v',
                'automobile',
                'asterisk',
                'at',
                'ban',
                'bank',
                'bar-chart-o',
                'barcode',
                'bars',
                'beer',
                'bell',
                'bell-o',
                'bell-slash',
                'bell-slash-o',
                'bicycle',
                'binoculars',
                'birthday-cake',
                'bolt',
                'bomb',
                'book',
                'bookmark',
                'bookmark-o',
                'briefcase',
                'bug',
                'building',
                'building-o',
                'bullhorn',
                'bullseye',
                'bus',
                'cab',
                'calculator',
                'calendar',
                'calendar-o',
                'camera',
                'camera-retro',
                'car',
                'caret-square-o-down',
                'caret-square-o-left',
                'caret-square-o-right',
                'caret-square-o-up',
                'cc',
                'cc-amex',
                'cc-discover',
                'cc-mastercard',
                'cc-paypal',
                'cc-stripe',
                'cc-visa',
                'certificate',
                'check',
                'check-circle',
                'check-circle-o',
                'check-square',
                'check-square-o',
                'child',
                'circle',
                'circle-o',
                'circle-thin',
                'clock-o',
                'cloud',
                'cloud-download',
                'cloud-upload',
                'code',
                'code-fork',
                'coffee',
                'cog',
                'cogs',
                'comment',
                'comment-o',
                'comments',
                'comments-o',
                'compass',
                'copyright',
                'credit-card',
                'crop',
                'crosshairs',
                'cube',
                'cubes',
                'cutlery',
                'dashboard',
                'desktop',
                'dashboard',
                'database',
                'desktop',
                'dot-circle-o',
                'download',
                'edit',
                'ellipsis-h',
                'ellipsis-v',
                'envelope',
                'envelope-o',
                'envelope-square',
                'eraser',
                'exchange',
                'exclamation',
                'exclamation-circle',
                'exclamation-triangle',
                'external-link',
                'external-link-square',
                'eye',
                'eye-slash',
                'eyedropper',
                'fax',
                'female',
                'fighter-jet',
                'file-archive-o',
                'file-audio-o',
                'file-code-o',
                'file-excel-o',
                'file-image-o',
                'file-movie-o',
                'file-pdf-o',
                'file-photo-o',
                'file-picture-o',
                'file-powerpoint-o',
                'file-sound-o',
                'file-video-o',
                'file-word-o',
                'file-zip-o',
                'film',
                'filter',
                'fire',
                'fire-extinguisher',
                'flag',
                'flag-checkered',
                'flag-o',
                'flash',
                'flask',
                'folder',
                'folder-o',
                'folder-open',
                'folder-open-o',
                'frown-o',
                'futbol-o',
                'gamepad',
                'gavel',
                'gear',
                'gears',
                'gift',
                'glass',
                'globe',
                'graduation-cap',
                'group',
                'hdd-o',
                'headphones',
                'heart',
                'heart-o',
                'history',
                'home',
                'image',
                'inbox',
                'info',
                'info-circle',
                'institution',
                'key',
                'keyboard-o',
                'language',
                'laptop',
                'leaf',
                'legal',
                'lemon-o',
                'level-down',
                'level-up',
                'life-bouy',
                'life-ring',
                'life-saver',
                'lightbulb-o',
                'line-chart',
                'location-arrow',
                'lock',
                'magic',
                'magnet',
                'mail-forward',
                'mail-reply',
                'mail-reply-all',
                'male',
                'map-marker',
                'meh-o',
                'microphone',
                'microphone-slash',
                'minus',
                'minus-circle',
                'minus-square',
                'minus-square-o',
                'mobile',
                'mobile-phone',
                'money',
                'moon-o',
                'mortar-board',
                'music',
                'navicon',
                'newspaper-o',
                'paint-brush',
                'paper-plane',
                'paper-plane-o',
                'paw',
                'pencil',
                'pencil-square',
                'pencil-square-o',
                'phone',
                'phone-square',
                'photo',
                'picture-o',
                'pie-chart',
                'plane',
                'plug',
                'plus',
                'plus-circle',
                'plus-square',
                'plus-square-o',
                'power-off',
                'print',
                'puzzle-piece',
                'qrcode',
                'question',
                'question-circle',
                'quote-left',
                'quote-right',
                'random',
                'refresh',
                'reorder',
                'reply',
                'reply-all',
                'retweet',
                'road',
                'rocket',
                'rss',
                'rss-square',
                'search',
                'search-minus',
                'search-plus',
                'send',
                'send-o',
                'share',
                'share-alt',
                'share-alt-square',
                'share-square',
                'share-square-o',
                'shield',
                'shopping-cart',
                'sign-in',
                'sign-out',
                'signal',
                'sitemap',
                'sliders',
                'smile-o',
                'soccer-ball-o',
                'sort',
                'sort-alpha-asc',
                'sort-alpha-desc',
                'sort-amount-asc',
                'sort-amount-desc',
                'sort-asc',
                'sort-desc',
                'sort-down',
                'sort-numeric-asc',
                'sort-numeric-desc',
                'sort-up',
                'space-shuttle',
                'spinner',
                'spoon',
                'square',
                'square-o',
                'star',
                'star-half',
                'star-half-empty',
                'star-half-full',
                'star-half-o',
                'star-o',
                'suitcase',
                'sun-o',
                'support',
                'tablet',
                'tachometer',
                'tag',
                'tags',
                'tasks',
                'taxi',
                'terminal',
                'thumb-tack',
                'thumbs-down',
                'thumbs-o-down',
                'thumbs-o-up',
                'thumbs-up',
                'ticket',
                'times',
                'times-circle',
                'times-circle-o',
                'tint',
                'toggle-down',
                'toggle-left',
                'toggle-off',
                'toggle-on',
                'toggle-right',
                'toggle-up',
                'trash',
                'trash-o',
                'tree',
                'trophy',
                'truck',
                'tty',
                'umbrella',
                'university',
                'unlock',
                'unlock-alt',
                'unsorted',
                'upload',
                'user',
                'users',
                'video-camera',
                'volume-down',
                'volume-off',
                'volume-up',
                'warning',
                'wheelchair',
                'wifi',
                'wrench',
                'check-square',
                'check-square-o',
                'circle',
                'circle-o',
                'dot-circle-o',
                'minus-square',
                'minus-square-o',
                'plus-square',
                'plus-square-o',
                'square',
                'square-o',
                'bitcoin',
                'btc',
                'cny',
                'dollar',
                'eur',
                'euro',
                'gbp',
                'ils',
                'inr',
                'jpy',
                'krw',
                'money',
                'rmb',
                'rouble',
                'rub',
                'ruble',
                'rupee',
                'shekel',
                'sheqel',
                'try',
                'turkish-lira',
                'usd',
                'won',
                'yen',
                'align-center',
                'align-justify',
                'align-left',
                'align-right',
                'bold',
                'chain',
                'chain-broken',
                'clipboard',
                'columns',
                'copy',
                'cut',
                'dedent',
                'eraser',
                'file',
                'file-o',
                'file-text',
                'file-text-o',
                'files-o',
                'floppy-o',
                'font',
                'header',
                'indent',
                'italic',
                'link',
                'list',
                'list-alt',
                'list-ol',
                'list-ul',
                'outdent',
                'paperclip',
                'paragraph',
                'paste',
                'repeat',
                'rotate-left',
                'rotate-right',
                'save',
                'scissors',
                'strikethrough',
                'subscript',
                'superscript',
                'table',
                'text-height',
                'text-width',
                'th',
                'th-large',
                'th-list',
                'underline',
                'undo',
                'unlink',
                'angle-double-down',
                'angle-double-left',
                'angle-double-right',
                'angle-double-up',
                'angle-down',
                'angle-left',
                'angle-right',
                'angle-up',
                'arrow-circle-down',
                'arrow-circle-left',
                'arrow-circle-o-down',
                'arrow-circle-o-left',
                'arrow-circle-o-right',
                'arrow-circle-o-up',
                'arrow-circle-right',
                'arrow-circle-up',
                'arrow-down',
                'arrow-left',
                'arrow-right',
                'arrow-up',
                'arrows',
                'arrows-alt',
                'arrows-h',
                'arrows-v',
                'caret-down',
                'caret-left',
                'caret-right',
                'caret-square-o-down',
                'caret-square-o-left',
                'caret-square-o-right',
                'caret-square-o-up',
                'caret-up',
                'chevron-circle-down',
                'chevron-circle-left',
                'chevron-circle-right',
                'chevron-circle-up',
                'chevron-down',
                'chevron-left',
                'chevron-right',
                'chevron-up',
                'hand-o-down',
                'hand-o-left',
                'hand-o-right',
                'hand-o-up',
                'long-arrow-down',
                'long-arrow-left',
                'long-arrow-right',
                'long-arrow-up',
                'toggle-down',
                'toggle-left',
                'toggle-right',
                'toggle-up',
                'arrows-alt',
                'backward',
                'compress',
                'eject',
                'expand',
                'fast-backward',
                'fast-forward',
                'forward',
                'pause',
                'play',
                'play-circle',
                'play-circle-o',
                'step-backward',
                'step-forward',
                'stop',
                'youtube-play',
                'adn',
                'android',
                'angellist',
                'apple',
                'behance',
                'behance-square',
                'bitbucket',
                'bitbucket-square',
                'bitcoin',
                'btc',
                'css3',
                'delicious',
                'digg',
                'dribbble',
                'dropbox',
                'drupal',
                'empire',
                'facebook',
                'facebook-square',
                'flickr',
                'foursquare',
                'ge',
                'git',
                'git-square',
                'github',
                'github-alt',
                'github-square',
                'gittip',
                'google',
                'google-plus',
                'google-plus-square',
                'google-wallet',
                'hacker-news',
                'html5',
                'instagram',
                'ioxhost',
                'joomla',
                'jsfiddle',
                'lastfm',
                'lastfm-square',
                'linkedin',
                'linkedin-square',
                'linux',
                'maxcdn',
                'meanpath',
                'openid',
                'pagelines',
                'paypal',
                'pied-piper',
                'pied-piper-alt',
                'pinterest',
                'pinterest-square',
                'qq',
                'ra',
                'rebel',
                'reddit',
                'reddit-square',
                'renren',
                'share-alt',
                'share-alt-square',
                'skype',
                'slack',
                'slideshare',
                'soundcloud',
                'spotify',
                'stack-exchange',
                'stack-overflow',
                'steam',
                'steam-square',
                'stumbleupon',
                'stumbleupon-circle',
                'tencent-weibo',
                'trello',
                'tumblr',
                'tumblr-square',
                'twitch',
                'twitter',
                'twitter-square',
                'vimeo-square',
                'vine',
                'vk',
                'wechat',
                'weibo',
                'weixin',
                'windows',
                'wordpress',
                'xing',
                'xing-square',
                'yahoo',
                'yelp',
                'youtube',
                'youtube-play',
                'youtube-square',
                'ambulance',
                'h-square',
                'hospital-o',
                'medkit',
                'plus-square',
                'stethoscope',
                'user-md',
                'wheelchair'
            ]
        };
    })(jQuery);;
    /*! RESOURCE: /scripts/bootstrap-iconpicker.js */
    ;
    (function($) {
        "use strict";
        var Iconpicker = function(element, options) {
            this.$element = $(element);
            this.options = $.extend({}, Iconpicker.DEFAULTS, this.$element.data());
            this.options = $.extend({}, this.options, options);
        };
        Iconpicker.ICONSET_EMPTY = {
            iconClass: '',
            iconClassFix: '',
            icons: []
        };
        Iconpicker.ICONSET = {
            _custom: null,
            elusiveicon: $.iconset_elusiveicon || Iconpicker.ICONSET_EMPTY,
            fontawesome: $.iconset_fontawesome || Iconpicker.ICONSET_EMPTY,
            ionicon: $.iconset_ionicon || Iconpicker.ICONSET_EMPTY,
            glyphicon: $.iconset_glyphicon || Iconpicker.ICONSET_EMPTY,
            mapicon: $.iconset_mapicon || Iconpicker.ICONSET_EMPTY,
            materialdesign: $.iconset_materialdesign || Iconpicker.ICONSET_EMPTY,
            octicon: $.iconset_octicon || Iconpicker.ICONSET_EMPTY,
            typicon: $.iconset_typicon || Iconpicker.ICONSET_EMPTY,
            weathericon: $.iconset_weathericon || Iconpicker.ICONSET_EMPTY
        };
        Iconpicker.DEFAULTS = {
            align: 'center',
            arrowClass: 'btn-primary',
            arrowNextIconClass: 'glyphicon glyphicon-arrow-right',
            arrowPrevIconClass: 'glyphicon glyphicon-arrow-left',
            cols: 4,
            icon: '',
            iconset: 'glyphicon',
            header: true,
            labelHeader: '{0} / {1}',
            footer: true,
            labelFooter: '{0} - {1} of {2}',
            placement: 'bottom',
            rows: 4,
            search: true,
            searchText: 'Search icon',
            selectedClass: 'btn-warning',
            unselectedClass: 'btn-default'
        };
        Iconpicker.prototype.bindEvents = function() {
            var op = this.options;
            var el = this;
            op.table.find('.btn-previous, .btn-next').off('click').on('click', function(e) {
                e.preventDefault();
                var inc = parseInt($(this).val(), 10);
                el.changeList(op.page + inc);
            });
            op.table.find('.btn-icon').off('click').on('click', function(e) {
                e.preventDefault();
                el.select($(this).val());
                if (op.inline === false) {
                    el.$element.popover('destroy');
                } else {
                    op.table.find('i.' + $(this).val()).parent().addClass(op.selectedClass);
                }
            });
            op.table.find('.search-control').off('keyup').on('keyup', function() {
                el.changeList(1);
            });
        };
        Iconpicker.prototype.changeList = function(page) {
            this.filterIcons();
            this.updateLabels(page);
            this.updateIcons(page);
            this.options.page = page;
            this.bindEvents();
        };
        Iconpicker.prototype.filterIcons = function() {
            var op = this.options;
            var search = op.table.find('.search-control').val();
            if (search === "") {
                op.icons = Iconpicker.ICONSET[op.iconset].icons;
            } else {
                var result = [];
                $.each(Iconpicker.ICONSET[op.iconset].icons, function(i, v) {
                    if (v.indexOf(search) > -1) {
                        result.push(v);
                    }
                });
                op.icons = result;
            }
        };
        Iconpicker.prototype.removeAddClass = function(target, remove, add) {
            this.options.table.find(target).removeClass(remove).addClass(add);
            return add;
        };
        Iconpicker.prototype.reset = function() {
            this.updatePicker();
            this.changeList(1);
        };
        Iconpicker.prototype.select = function(icon) {
            var op = this.options;
            var el = this.$element;
            op.selected = $.inArray(icon.replace(op.iconClassFix, ''), op.icons);
            if (op.selected === -1) {
                op.selected = 0;
                icon = op.iconClassFix + op.icons[op.selected];
            }
            if (icon !== '' && op.selected >= 0) {
                op.icon = icon;
                if (op.inline === false) {
                    el.find('input').val(icon);
                    el.find('i').attr('class', '').addClass(op.iconClass).addClass(icon);
                }
                if (icon === op.iconClassFix) {
                    el.trigger({
                        type: "change",
                        icon: 'empty'
                    });
                } else {
                    el.trigger({
                        type: "change",
                        icon: icon
                    });
                }
                op.table.find('button.' + op.selectedClass).removeClass(op.selectedClass);
            }
        };
        Iconpicker.prototype.switchPage = function(icon) {
            var op = this.options;
            op.selected = $.inArray(icon.replace(op.iconClassFix, ''), op.icons);
            if (op.selected >= 0) {
                var page = Math.ceil((op.selected + 1) / this.totalIconsPerPage());
                this.changeList(page);
            }
            if (icon === '') {
                op.table.find('i.' + op.iconClassFix).parent().addClass(op.selectedClass);
            } else {
                op.table.find('i.' + icon).parent().addClass(op.selectedClass);
            }
        };
        Iconpicker.prototype.totalPages = function() {
            return Math.ceil(this.totalIcons() / this.totalIconsPerPage());
        };
        Iconpicker.prototype.totalIcons = function() {
            return this.options.icons.length;
        };
        Iconpicker.prototype.totalIconsPerPage = function() {
            if (this.options.rows === 0) {
                return this.options.icons.length;
            } else {
                return this.options.cols * this.options.rows;
            }
        };
        Iconpicker.prototype.updateArrows = function(page) {
            var op = this.options;
            var total_pages = this.totalPages();
            if (page === 1) {
                op.table.find('.btn-previous').addClass('disabled');
            } else {
                op.table.find('.btn-previous').removeClass('disabled');
            }
            if (page === total_pages || total_pages === 0) {
                op.table.find('.btn-next').addClass('disabled');
            } else {
                op.table.find('.btn-next').removeClass('disabled');
            }
        };
        Iconpicker.prototype.updateIcons = function(page) {
            var op = this.options;
            var tbody = op.table.find('tbody').empty();
            var offset = (page - 1) * this.totalIconsPerPage();
            var length = op.rows;
            if (op.rows === 0) {
                length = op.icons.length;
            }
            for (var i = 0; i < length; i++) {
                var tr = $('<tr></tr>');
                for (var j = 0; j < op.cols; j++) {
                    var pos = offset + (i * op.cols) + j;
                    var btn = $('<button class="btn ' + op.unselectedClass + ' btn-icon"></button>').hide();
                    if (pos < op.icons.length) {
                        var v = op.iconClassFix + op.icons[pos];
                        btn.val(v).attr('title', v).append('<i class="' + op.iconClass + ' ' + v + '"></i>').show();
                        if (op.icon === v) {
                            btn.addClass(op.selectedClass).addClass('btn-icon-selected');
                        }
                    }
                    tr.append($('<td></td>').append(btn));
                }
                tbody.append(tr);
            }
        };
        Iconpicker.prototype.updateIconsCount = function() {
            var op = this.options;
            if (op.footer === true) {
                var icons_count = [
                    '<tr>',
                    '   <td colspan="' + op.cols + '" class="text-center">',
                    '       <span class="icons-count"></span>',
                    '   </td>',
                    '</tr>'
                ];
                op.table.find('tfoot').empty().append(icons_count.join(''));
            }
        };
        Iconpicker.prototype.updateLabels = function(page) {
            var op = this.options;
            var total_icons = this.totalIcons();
            var total_pages = this.totalPages();
            op.table.find('.page-count').html(op.labelHeader.replace('{0}', (total_pages === 0) ? 0 : page).replace('{1}', total_pages));
            var offset = (page - 1) * this.totalIconsPerPage();
            var total = page * this.totalIconsPerPage();
            op.table.find('.icons-count').html(op.labelFooter.replace('{0}', total_icons ? offset + 1 : 0).replace('{1}', (total < total_icons) ? total : total_icons).replace('{2}', total_icons));
            this.updateArrows(page);
        };
        Iconpicker.prototype.updatePagesCount = function() {
            var op = this.options;
            if (op.header === true) {
                var tr = $('<tr></tr>');
                for (var i = 0; i < op.cols; i++) {
                    var td = $('<td class="text-center"></td>');
                    if (i === 0 || i === op.cols - 1) {
                        var arrow = [
                            '<button class="btn btn-arrow ' + ((i === 0) ? 'btn-previous' : 'btn-next') + ' ' + op.arrowClass + '" value="' + ((i === 0) ? -1 : 1) + '">',
                            '<span class="' + ((i === 0) ? op.arrowPrevIconClass : op.arrowNextIconClass) + '"></span>',
                            '</button>'
                        ];
                        td.append(arrow.join(''));
                        tr.append(td);
                    } else if (tr.find('.page-count').length === 0) {
                        td.attr('colspan', op.cols - 2).append('<span class="page-count"></span>');
                        tr.append(td);
                    }
                }
                op.table.find('thead').empty().append(tr);
            }
        };
        Iconpicker.prototype.updatePicker = function() {
            var op = this.options;
            if (op.cols < 4) {
                throw 'Iconpicker => The number of columns must be greater than or equal to 4. [option.cols = ' + op.cols + ']';
            } else if (op.rows < 0) {
                throw 'Iconpicker => The number of rows must be greater than or equal to 0. [option.rows = ' + op.rows + ']';
            } else {
                this.updatePagesCount();
                this.updateSearch();
                this.updateIconsCount();
            }
        };
        Iconpicker.prototype.updateSearch = function() {
            var op = this.options;
            var search = [
                '<tr style="display: table-row;">',
                '   <td colspan="' + op.cols + '">',
                '       <input type="text" class="form-control search-control" style="width: ' + op.cols * 39 + 'px;" placeholder="' + op.searchText + '">',
                '   </td>',
                '</tr>'
            ];
            search = $(search.join(''));
            if (op.search === true) {
                search.show();
            } else {
                search.hide();
            }
            op.table.find('thead').append(search);
        };
        Iconpicker.prototype.setAlign = function(value) {
            this.$element.removeClass(this.options.align).addClass(value);
            this.options.align = value;
        };
        Iconpicker.prototype.setArrowClass = function(value) {
            this.options.arrowClass = this.removeAddClass('.btn-arrow', this.options.arrowClass, value);
        };
        Iconpicker.prototype.setArrowNextIconClass = function(value) {
            this.options.arrowNextIconClass = this.removeAddClass('.btn-next > span', this.options.arrowNextIconClass, value);
        };
        Iconpicker.prototype.setArrowPrevIconClass = function(value) {
            this.options.arrowPrevIconClass = this.removeAddClass('.btn-previous > span', this.options.arrowPrevIconClass, value);
        };
        Iconpicker.prototype.setCols = function(value) {
            this.options.cols = value;
            this.reset();
        };
        Iconpicker.prototype.setFooter = function(value) {
            var footer = this.options.table.find('tfoot');
            if (value === true) {
                footer.show();
            } else {
                footer.hide();
            }
            this.options.footer = value;
        };
        Iconpicker.prototype.setHeader = function(value) {
            var header = this.options.table.find('thead');
            if (value === true) {
                header.show();
            } else {
                header.hide();
            }
            this.options.header = value;
        };
        Iconpicker.prototype.setIcon = function(value) {
            this.select(value);
        };
        Iconpicker.prototype.setIconset = function(value) {
            var op = this.options;
            if ($.isPlainObject(value)) {
                Iconpicker.ICONSET._custom = $.extend(Iconpicker.ICONSET_EMPTY, value);
                op.iconset = '_custom';
            } else if (!Iconpicker.ICONSET.hasOwnProperty(value)) {
                op.iconset = Iconpicker.DEFAULTS.iconset;
            } else {
                op.iconset = value;
            }
            op = $.extend(op, Iconpicker.ICONSET[op.iconset]);
            this.reset();
            this.select(op.icon);
        };
        Iconpicker.prototype.setLabelHeader = function(value) {
            this.options.labelHeader = value;
            this.updateLabels(this.options.page);
        };
        Iconpicker.prototype.setLabelFooter = function(value) {
            this.options.labelFooter = value;
            this.updateLabels(this.options.page);
        };
        Iconpicker.prototype.setPlacement = function(value) {
            this.options.placement = value;
        };
        Iconpicker.prototype.setRows = function(value) {
            this.options.rows = value;
            this.reset();
        };
        Iconpicker.prototype.setSearch = function(value) {
            var search = this.options.table.find('.search-control');
            if (value === true) {
                search.show();
            } else {
                search.hide();
            }
            search.val('');
            this.changeList(1);
            this.options.search = value;
        };
        Iconpicker.prototype.setSearchText = function(value) {
            this.options.table.find('.search-control').attr('placeholder', value);
            this.options.searchText = value;
        };
        Iconpicker.prototype.setSelectedClass = function(value) {
            this.options.selectedClass = this.removeAddClass('.btn-icon-selected', this.options.selectedClass, value);
        };
        Iconpicker.prototype.setUnselectedClass = function(value) {
            this.options.unselectedClass = this.removeAddClass('.btn-icon', this.options.unselectedClass, value);
        };
        var old = $.fn.iconpicker;
        $.fn.iconpicker = function(option, params) {
            return this.each(function() {
                var $this = $(this);
                var data = $this.data('bs.iconpicker');
                var options = typeof option === 'object' && option;
                if (!data) {
                    $this.data('bs.iconpicker', (data = new Iconpicker(this, options)));
                }
                if (typeof option === 'string') {
                    if (typeof data[option] === 'undefined') {
                        throw 'Iconpicker => The "' + option + '" method does not exists.';
                    } else {
                        data[option](params);
                    }
                } else {
                    var op = data.options;
                    op = $.extend(op, {
                        inline: false,
                        page: 1,
                        selected: -1,
                        table: $('<table class="table-icons"><thead></thead><tbody></tbody><tfoot></tfoot></table>')
                    });
                    var name = (typeof $this.attr('name') !== 'undefined') ? 'name="' + $this.attr('name') + '"' : '';
                    if ($this.prop('tagName') === 'BUTTON') {
                        $this.empty()
                            .append('<i></i>')
                            .append('<input type="hidden" ' + name + '></input>')
                            .append('<span class="caret"></span>')
                            .addClass('iconpicker');
                        data.setIconset(op.iconset);
                        $this.on('click', function(e) {
                            e.preventDefault();
                            $this.popover({
                                animation: false,
                                trigger: 'manual',
                                html: true,
                                content: op.table,
                                container: 'body',
                                placement: op.placement
                            }).on('shown.bs.popover', function() {
                                data.switchPage(op.icon);
                                data.bindEvents();
                            });
                            $this.data('bs.popover').tip().addClass('iconpicker-popover');
                            $this.popover('show');
                        });
                    } else {
                        op.inline = true;
                        data.setIconset(op.iconset);
                        $this.empty()
                            .append('<input type="hidden" ' + name + '></input>')
                            .append(op.table)
                            .addClass('iconpicker')
                            .addClass(op.align);
                        data.switchPage(op.icon);
                        data.bindEvents();
                    }
                }
            });
        };
        $.fn.iconpicker.Constructor = Iconpicker;
        $.fn.iconpicker.noConflict = function() {
            $.fn.iconpicker = old;
            return this;
        };
        $(document).on('click', 'body', function(e) {
            $('.iconpicker').each(function() {
                if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
                    $(this).popover('destroy');
                }
            });
        });
        $('button[role="iconpicker"],div[role="iconpicker"]').iconpicker();
    })(jQuery);;
    /*! RESOURCE: /scripts/angularjs-1.4/thirdparty/angular-ui-bootstrap/ui-bootstrap-tpls-1.1.2.js */
    angular.module("ui.bootstrap", ["ui.bootstrap.tpls", "ui.bootstrap.collapse", "ui.bootstrap.accordion", "ui.bootstrap.alert", "ui.bootstrap.buttons", "ui.bootstrap.carousel", "ui.bootstrap.dateparser", "ui.bootstrap.isClass", "ui.bootstrap.position", "ui.bootstrap.datepicker", "ui.bootstrap.debounce", "ui.bootstrap.dropdown", "ui.bootstrap.stackedMap", "ui.bootstrap.modal", "ui.bootstrap.paging", "ui.bootstrap.pager", "ui.bootstrap.pagination", "ui.bootstrap.tooltip", "ui.bootstrap.popover", "ui.bootstrap.progressbar", "ui.bootstrap.rating", "ui.bootstrap.tabs", "ui.bootstrap.timepicker", "ui.bootstrap.typeahead"]);
    angular.module("ui.bootstrap.tpls", ["uib/template/accordion/accordion-group.html", "uib/template/accordion/accordion.html", "uib/template/alert/alert.html", "uib/template/carousel/carousel.html", "uib/template/carousel/slide.html", "uib/template/datepicker/datepicker.html", "uib/template/datepicker/day.html", "uib/template/datepicker/month.html", "uib/template/datepicker/popup.html", "uib/template/datepicker/year.html", "uib/template/modal/backdrop.html", "uib/template/modal/window.html", "uib/template/pager/pager.html", "uib/template/pagination/pagination.html", "uib/template/tooltip/tooltip-html-popup.html", "uib/template/tooltip/tooltip-popup.html", "uib/template/tooltip/tooltip-template-popup.html", "uib/template/popover/popover-html.html", "uib/template/popover/popover-template.html", "uib/template/popover/popover.html", "uib/template/progressbar/bar.html", "uib/template/progressbar/progress.html", "uib/template/progressbar/progressbar.html", "uib/template/rating/rating.html", "uib/template/tabs/tab.html", "uib/template/tabs/tabset.html", "uib/template/timepicker/timepicker.html", "uib/template/typeahead/typeahead-match.html", "uib/template/typeahead/typeahead-popup.html"]);
    angular.module('ui.bootstrap.collapse', [])
        .directive('uibCollapse', ['$animate', '$q', '$parse', '$injector', function($animate, $q, $parse, $injector) {
            var $animateCss = $injector.has('$animateCss') ? $injector.get('$animateCss') : null;
            return {
                link: function(scope, element, attrs) {
                    var expandingExpr = $parse(attrs.expanding),
                        expandedExpr = $parse(attrs.expanded),
                        collapsingExpr = $parse(attrs.collapsing),
                        collapsedExpr = $parse(attrs.collapsed);
                    if (!scope.$eval(attrs.uibCollapse)) {
                        element.addClass('in')
                            .addClass('collapse')
                            .attr('aria-expanded', true)
                            .attr('aria-hidden', false)
                            .css({
                                height: 'auto'
                            });
                    }
    
                    function expand() {
                        if (element.hasClass('collapse') && element.hasClass('in')) {
                            return;
                        }
                        $q.resolve(expandingExpr(scope))
                            .then(function() {
                                element.removeClass('collapse')
                                    .addClass('collapsing')
                                    .attr('aria-expanded', true)
                                    .attr('aria-hidden', false);
                                if ($animateCss) {
                                    $animateCss(element, {
                                        addClass: 'in',
                                        easing: 'ease',
                                        to: {
                                            height: element[0].scrollHeight + 'px'
                                        }
                                    }).start()['finally'](expandDone);
                                } else {
                                    $animate.addClass(element, 'in', {
                                        to: {
                                            height: element[0].scrollHeight + 'px'
                                        }
                                    }).then(expandDone);
                                }
                            });
                    }
    
                    function expandDone() {
                        element.removeClass('collapsing')
                            .addClass('collapse')
                            .css({
                                height: 'auto'
                            });
                        expandedExpr(scope);
                    }
    
                    function collapse() {
                        if (!element.hasClass('collapse') && !element.hasClass('in')) {
                            return collapseDone();
                        }
                        $q.resolve(collapsingExpr(scope))
                            .then(function() {
                                element
                                    .css({
                                        height: element[0].scrollHeight + 'px'
                                    })
                                    .removeClass('collapse')
                                    .addClass('collapsing')
                                    .attr('aria-expanded', false)
                                    .attr('aria-hidden', true);
                                if ($animateCss) {
                                    $animateCss(element, {
                                        removeClass: 'in',
                                        to: {
                                            height: '0'
                                        }
                                    }).start()['finally'](collapseDone);
                                } else {
                                    $animate.removeClass(element, 'in', {
                                        to: {
                                            height: '0'
                                        }
                                    }).then(collapseDone);
                                }
                            });
                    }
    
                    function collapseDone() {
                        element.css({
                            height: '0'
                        });
                        element.removeClass('collapsing')
                            .addClass('collapse');
                        collapsedExpr(scope);
                    }
                    scope.$watch(attrs.uibCollapse, function(shouldCollapse) {
                        if (shouldCollapse) {
                            collapse();
                        } else {
                            expand();
                        }
                    });
                }
            };
        }]);
    angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
        .constant('uibAccordionConfig', {
            closeOthers: true
        })
        .controller('UibAccordionController', ['$scope', '$attrs', 'uibAccordionConfig', function($scope, $attrs, accordionConfig) {
            this.groups = [];
            this.closeOthers = function(openGroup) {
                var closeOthers = angular.isDefined($attrs.closeOthers) ?
                    $scope.$eval($attrs.closeOthers) : accordionConfig.closeOthers;
                if (closeOthers) {
                    angular.forEach(this.groups, function(group) {
                        if (group !== openGroup) {
                            group.isOpen = false;
                        }
                    });
                }
            };
            this.addGroup = function(groupScope) {
                var that = this;
                this.groups.push(groupScope);
                groupScope.$on('$destroy', function(event) {
                    that.removeGroup(groupScope);
                });
            };
            this.removeGroup = function(group) {
                var index = this.groups.indexOf(group);
                if (index !== -1) {
                    this.groups.splice(index, 1);
                }
            };
        }])
        .directive('uibAccordion', function() {
            return {
                controller: 'UibAccordionController',
                controllerAs: 'accordion',
                transclude: true,
                templateUrl: function(element, attrs) {
                    return attrs.templateUrl || 'uib/template/accordion/accordion.html';
                }
            };
        })
        .directive('uibAccordionGroup', function() {
            return {
                require: '^uibAccordion',
                transclude: true,
                replace: true,
                templateUrl: function(element, attrs) {
                    return attrs.templateUrl || 'uib/template/accordion/accordion-group.html';
                },
                scope: {
                    heading: '@',
                    isOpen: '=?',
                    isDisabled: '=?'
                },
                controller: function() {
                    this.setHeading = function(element) {
                        this.heading = element;
                    };
                },
                link: function(scope, element, attrs, accordionCtrl) {
                    accordionCtrl.addGroup(scope);
                    scope.openClass = attrs.openClass || 'panel-open';
                    scope.panelClass = attrs.panelClass || 'panel-default';
                    scope.$watch('isOpen', function(value) {
                        element.toggleClass(scope.openClass, !!value);
                        if (value) {
                            accordionCtrl.closeOthers(scope);
                        }
                    });
                    scope.toggleOpen = function($event) {
                        if (!scope.isDisabled) {
                            if (!$event || $event.which === 32) {
                                scope.isOpen = !scope.isOpen;
                            }
                        }
                    };
                    var id = 'accordiongroup-' + scope.$id + '-' + Math.floor(Math.random() * 10000);
                    scope.headingId = id + '-tab';
                    scope.panelId = id + '-panel';
                }
            };
        })
        .directive('uibAccordionHeading', function() {
            return {
                transclude: true,
                template: '',
                replace: true,
                require: '^uibAccordionGroup',
                link: function(scope, element, attrs, accordionGroupCtrl, transclude) {
                    accordionGroupCtrl.setHeading(transclude(scope, angular.noop));
                }
            };
        })
        .directive('uibAccordionTransclude', function() {
            return {
                require: '^uibAccordionGroup',
                link: function(scope, element, attrs, controller) {
                    scope.$watch(function() {
                        return controller[attrs.uibAccordionTransclude];
                    }, function(heading) {
                        if (heading) {
                            element.find('span').html('');
                            element.find('span').append(heading);
                        }
                    });
                }
            };
        });
    angular.module('ui.bootstrap.alert', [])
        .controller('UibAlertController', ['$scope', '$attrs', '$interpolate', '$timeout', function($scope, $attrs, $interpolate, $timeout) {
            $scope.closeable = !!$attrs.close;
            var dismissOnTimeout = angular.isDefined($attrs.dismissOnTimeout) ?
                $interpolate($attrs.dismissOnTimeout)($scope.$parent) : null;
            if (dismissOnTimeout) {
                $timeout(function() {
                    $scope.close();
                }, parseInt(dismissOnTimeout, 10));
            }
        }])
        .directive('uibAlert', function() {
            return {
                controller: 'UibAlertController',
                controllerAs: 'alert',
                templateUrl: function(element, attrs) {
                    return attrs.templateUrl || 'uib/template/alert/alert.html';
                },
                transclude: true,
                replace: true,
                scope: {
                    type: '@',
                    close: '&'
                }
            };
        });
    angular.module('ui.bootstrap.buttons', [])
        .constant('uibButtonConfig', {
            activeClass: 'active',
            toggleEvent: 'click'
        })
        .controller('UibButtonsController', ['uibButtonConfig', function(buttonConfig) {
            this.activeClass = buttonConfig.activeClass || 'active';
            this.toggleEvent = buttonConfig.toggleEvent || 'click';
        }])
        .directive('uibBtnRadio', ['$parse', function($parse) {
            return {
                require: ['uibBtnRadio', 'ngModel'],
                controller: 'UibButtonsController',
                controllerAs: 'buttons',
                link: function(scope, element, attrs, ctrls) {
                    var buttonsCtrl = ctrls[0],
                        ngModelCtrl = ctrls[1];
                    var uncheckableExpr = $parse(attrs.uibUncheckable);
                    element.find('input').css({
                        display: 'none'
                    });
                    ngModelCtrl.$render = function() {
                        element.toggleClass(buttonsCtrl.activeClass, angular.equals(ngModelCtrl.$modelValue, scope.$eval(attrs.uibBtnRadio)));
                    };
                    element.on(buttonsCtrl.toggleEvent, function() {
                        if (attrs.disabled) {
                            return;
                        }
                        var isActive = element.hasClass(buttonsCtrl.activeClass);
                        if (!isActive || angular.isDefined(attrs.uncheckable)) {
                            scope.$apply(function() {
                                ngModelCtrl.$setViewValue(isActive ? null : scope.$eval(attrs.uibBtnRadio));
                                ngModelCtrl.$render();
                            });
                        }
                    });
                    if (attrs.uibUncheckable) {
                        scope.$watch(uncheckableExpr, function(uncheckable) {
                            attrs.$set('uncheckable', uncheckable ? '' : null);
                        });
                    }
                }
            };
        }])
        .directive('uibBtnCheckbox', function() {
            return {
                require: ['uibBtnCheckbox', 'ngModel'],
                controller: 'UibButtonsController',
                controllerAs: 'button',
                link: function(scope, element, attrs, ctrls) {
                    var buttonsCtrl = ctrls[0],
                        ngModelCtrl = ctrls[1];
                    element.find('input').css({
                        display: 'none'
                    });
    
                    function getTrueValue() {
                        return getCheckboxValue(attrs.btnCheckboxTrue, true);
                    }
    
                    function getFalseValue() {
                        return getCheckboxValue(attrs.btnCheckboxFalse, false);
                    }
    
                    function getCheckboxValue(attribute, defaultValue) {
                        return angular.isDefined(attribute) ? scope.$eval(attribute) : defaultValue;
                    }
                    ngModelCtrl.$render = function() {
                        element.toggleClass(buttonsCtrl.activeClass, angular.equals(ngModelCtrl.$modelValue, getTrueValue()));
                    };
                    element.on(buttonsCtrl.toggleEvent, function() {
                        if (attrs.disabled) {
                            return;
                        }
                        scope.$apply(function() {
                            ngModelCtrl.$setViewValue(element.hasClass(buttonsCtrl.activeClass) ? getFalseValue() : getTrueValue());
                            ngModelCtrl.$render();
                        });
                    });
                }
            };
        });
    angular.module('ui.bootstrap.carousel', [])
        .controller('UibCarouselController', ['$scope', '$element', '$interval', '$timeout', '$animate', function($scope, $element, $interval, $timeout, $animate) {
            var self = this,
                slides = self.slides = $scope.slides = [],
                SLIDE_DIRECTION = 'uib-slideDirection',
                currentIndex = -1,
                currentInterval, isPlaying, bufferedTransitions = [];
            self.currentSlide = null;
            var destroyed = false;
            self.addSlide = function(slide, element) {
                slide.$element = element;
                slides.push(slide);
                if (slides.length === 1 || slide.active) {
                    if ($scope.$currentTransition) {
                        $scope.$currentTransition = null;
                    }
                    self.select(slides[slides.length - 1]);
                    if (slides.length === 1) {
                        $scope.play();
                    }
                } else {
                    slide.active = false;
                }
            };
            self.getCurrentIndex = function() {
                if (self.currentSlide && angular.isDefined(self.currentSlide.index)) {
                    return +self.currentSlide.index;
                }
                return currentIndex;
            };
            self.next = $scope.next = function() {
                var newIndex = (self.getCurrentIndex() + 1) % slides.length;
                if (newIndex === 0 && $scope.noWrap()) {
                    $scope.pause();
                    return;
                }
                return self.select(getSlideByIndex(newIndex), 'next');
            };
            self.prev = $scope.prev = function() {
                var newIndex = self.getCurrentIndex() - 1 < 0 ? slides.length - 1 : self.getCurrentIndex() - 1;
                if ($scope.noWrap() && newIndex === slides.length - 1) {
                    $scope.pause();
                    return;
                }
                return self.select(getSlideByIndex(newIndex), 'prev');
            };
            self.removeSlide = function(slide) {
                if (angular.isDefined(slide.index)) {
                    slides.sort(function(a, b) {
                        return +a.index > +b.index;
                    });
                }
                var bufferedIndex = bufferedTransitions.indexOf(slide);
                if (bufferedIndex !== -1) {
                    bufferedTransitions.splice(bufferedIndex, 1);
                }
                var index = slides.indexOf(slide);
                slides.splice(index, 1);
                $timeout(function() {
                    if (slides.length > 0 && slide.active) {
                        if (index >= slides.length) {
                            self.select(slides[index - 1]);
                        } else {
                            self.select(slides[index]);
                        }
                    } else if (currentIndex > index) {
                        currentIndex--;
                    }
                });
                if (slides.length === 0) {
                    self.currentSlide = null;
                    clearBufferedTransitions();
                }
            };
            self.select = $scope.select = function(nextSlide, direction) {
                var nextIndex = $scope.indexOfSlide(nextSlide);
                if (direction === undefined) {
                    direction = nextIndex > self.getCurrentIndex() ? 'next' : 'prev';
                }
                if (nextSlide && nextSlide !== self.currentSlide && !$scope.$currentTransition) {
                    goNext(nextSlide, nextIndex, direction);
                } else if (nextSlide && nextSlide !== self.currentSlide && $scope.$currentTransition) {
                    bufferedTransitions.push(nextSlide);
                    nextSlide.active = false;
                }
            };
            $scope.indexOfSlide = function(slide) {
                return angular.isDefined(slide.index) ? +slide.index : slides.indexOf(slide);
            };
            $scope.isActive = function(slide) {
                return self.currentSlide === slide;
            };
            $scope.pause = function() {
                if (!$scope.noPause) {
                    isPlaying = false;
                    resetTimer();
                }
            };
            $scope.play = function() {
                if (!isPlaying) {
                    isPlaying = true;
                    restartTimer();
                }
            };
            $scope.$on('$destroy', function() {
                destroyed = true;
                resetTimer();
            });
            $scope.$watch('noTransition', function(noTransition) {
                $animate.enabled($element, !noTransition);
            });
            $scope.$watch('interval', restartTimer);
            $scope.$watchCollection('slides', resetTransition);
    
            function clearBufferedTransitions() {
                while (bufferedTransitions.length) {
                    bufferedTransitions.shift();
                }
            }
    
            function getSlideByIndex(index) {
                if (angular.isUndefined(slides[index].index)) {
                    return slides[index];
                }
                for (var i = 0, l = slides.length; i < l; ++i) {
                    if (slides[i].index === index) {
                        return slides[i];
                    }
                }
            }
    
            function goNext(slide, index, direction) {
                if (destroyed) {
                    return;
                }
                angular.extend(slide, {
                    direction: direction,
                    active: true
                });
                angular.extend(self.currentSlide || {}, {
                    direction: direction,
                    active: false
                });
                if ($animate.enabled($element) && !$scope.$currentTransition &&
                    slide.$element && self.slides.length > 1) {
                    slide.$element.data(SLIDE_DIRECTION, slide.direction);
                    if (self.currentSlide && self.currentSlide.$element) {
                        self.currentSlide.$element.data(SLIDE_DIRECTION, slide.direction);
                    }
                    $scope.$currentTransition = true;
                    $animate.on('addClass', slide.$element, function(element, phase) {
                        if (phase === 'close') {
                            $scope.$currentTransition = null;
                            $animate.off('addClass', element);
                            if (bufferedTransitions.length) {
                                var nextSlide = bufferedTransitions.pop();
                                var nextIndex = $scope.indexOfSlide(nextSlide);
                                var nextDirection = nextIndex > self.getCurrentIndex() ? 'next' : 'prev';
                                clearBufferedTransitions();
                                goNext(nextSlide, nextIndex, nextDirection);
                            }
                        }
                    });
                }
                self.currentSlide = slide;
                currentIndex = index;
                restartTimer();
            }
    
            function resetTimer() {
                if (currentInterval) {
                    $interval.cancel(currentInterval);
                    currentInterval = null;
                }
            }
    
            function resetTransition(slides) {
                if (!slides.length) {
                    $scope.$currentTransition = null;
                    clearBufferedTransitions();
                }
            }
    
            function restartTimer() {
                resetTimer();
                var interval = +$scope.interval;
                if (!isNaN(interval) && interval > 0) {
                    currentInterval = $interval(timerFn, interval);
                }
            }
    
            function timerFn() {
                var interval = +$scope.interval;
                if (isPlaying && !isNaN(interval) && interval > 0 && slides.length) {
                    $scope.next();
                } else {
                    $scope.pause();
                }
            }
        }])
        .directive('uibCarousel', function() {
            return {
                transclude: true,
                replace: true,
                controller: 'UibCarouselController',
                controllerAs: 'carousel',
                templateUrl: function(element, attrs) {
                    return attrs.templateUrl || 'uib/template/carousel/carousel.html';
                },
                scope: {
                    interval: '=',
                    noTransition: '=',
                    noPause: '=',
                    noWrap: '&'
                }
            };
        })
        .directive('uibSlide', function() {
            return {
                require: '^uibCarousel',
                transclude: true,
                replace: true,
                templateUrl: function(element, attrs) {
                    return attrs.templateUrl || 'uib/template/carousel/slide.html';
                },
                scope: {
                    active: '=?',
                    actual: '=?',
                    index: '=?'
                },
                link: function(scope, element, attrs, carouselCtrl) {
                    carouselCtrl.addSlide(scope, element);
                    scope.$on('$destroy', function() {
                        carouselCtrl.removeSlide(scope);
                    });
                    scope.$watch('active', function(active) {
                        if (active) {
                            carouselCtrl.select(scope);
                        }
                    });
                }
            };
        })
        .animation('.item', ['$animateCss',
            function($animateCss) {
                var SLIDE_DIRECTION = 'uib-slideDirection';
    
                function removeClass(element, className, callback) {
                    element.removeClass(className);
                    if (callback) {
                        callback();
                    }
                }
                return {
                    beforeAddClass: function(element, className, done) {
                        if (className === 'active') {
                            var stopped = false;
                            var direction = element.data(SLIDE_DIRECTION);
                            var directionClass = direction === 'next' ? 'left' : 'right';
                            var removeClassFn = removeClass.bind(this, element,
                                directionClass + ' ' + direction, done);
                            element.addClass(direction);
                            $animateCss(element, {
                                    addClass: directionClass
                                })
                                .start()
                                .done(removeClassFn);
                            return function() {
                                stopped = true;
                            };
                        }
                        done();
                    },
                    beforeRemoveClass: function(element, className, done) {
                        if (className === 'active') {
                            var stopped = false;
                            var direction = element.data(SLIDE_DIRECTION);
                            var directionClass = direction === 'next' ? 'left' : 'right';
                            var removeClassFn = removeClass.bind(this, element, directionClass, done);
                            $animateCss(element, {
                                    addClass: directionClass
                                })
                                .start()
                                .done(removeClassFn);
                            return function() {
                                stopped = true;
                            };
                        }
                        done();
                    }
                };
            }
        ]);
    angular.module('ui.bootstrap.dateparser', [])
        .service('uibDateParser', ['$log', '$locale', 'dateFilter', 'orderByFilter', function($log, $locale, dateFilter, orderByFilter) {
            var SPECIAL_CHARACTERS_REGEXP = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
            var localeId;
            var formatCodeToRegex;
            this.init = function() {
                localeId = $locale.id;
                this.parsers = {};
                this.formatters = {};
                formatCodeToRegex = [{
                        key: 'yyyy',
                        regex: '\\d{4}',
                        apply: function(value) {
                            this.year = +value;
                        },
                        formatter: function(date) {
                            var _date = new Date();
                            _date.setFullYear(Math.abs(date.getFullYear()));
                            return dateFilter(_date, 'yyyy');
                        }
                    },
                    {
                        key: 'yy',
                        regex: '\\d{2}',
                        apply: function(value) {
                            this.year = +value + 2000;
                        },
                        formatter: function(date) {
                            var _date = new Date();
                            _date.setFullYear(Math.abs(date.getFullYear()));
                            return dateFilter(_date, 'yy');
                        }
                    },
                    {
                        key: 'y',
                        regex: '\\d{1,4}',
                        apply: function(value) {
                            this.year = +value;
                        },
                        formatter: function(date) {
                            var _date = new Date();
                            _date.setFullYear(Math.abs(date.getFullYear()));
                            return dateFilter(_date, 'y');
                        }
                    },
                    {
                        key: 'M!',
                        regex: '0?[1-9]|1[0-2]',
                        apply: function(value) {
                            this.month = value - 1;
                        },
                        formatter: function(date) {
                            var value = date.getMonth();
                            if (/^[0-9]$/.test(value)) {
                                return dateFilter(date, 'MM');
                            }
                            return dateFilter(date, 'M');
                        }
                    },
                    {
                        key: 'MMMM',
                        regex: $locale.DATETIME_FORMATS.MONTH.join('|'),
                        apply: function(value) {
                            this.month = $locale.DATETIME_FORMATS.MONTH.indexOf(value);
                        },
                        formatter: function(date) {
                            return dateFilter(date, 'MMMM');
                        }
                    },
                    {
                        key: 'MMM',
                        regex: $locale.DATETIME_FORMATS.SHORTMONTH.join('|'),
                        apply: function(value) {
                            this.month = $locale.DATETIME_FORMATS.SHORTMONTH.indexOf(value);
                        },
                        formatter: function(date) {
                            return dateFilter(date, 'MMM');
                        }
                    },
                    {
                        key: 'MM',
                        regex: '0[1-9]|1[0-2]',
                        apply: function(value) {
                            this.month = value - 1;
                        },
                        formatter: function(date) {
                            return dateFilter(date, 'MM');
                        }
                    },
                    {
                        key: 'M',
                        regex: '[1-9]|1[0-2]',
                        apply: function(value) {
                            this.month = value - 1;
                        },
                        formatter: function(date) {
                            return dateFilter(date, 'M');
                        }
                    },
                    {
                        key: 'd!',
                        regex: '[0-2]?[0-9]{1}|3[0-1]{1}',
                        apply: function(value) {
                            this.date = +value;
                        },
                        formatter: function(date) {
                            var value = date.getDate();
                            if (/^[1-9]$/.test(value)) {
                                return dateFilter(date, 'dd');
                            }
                            return dateFilter(date, 'd');
                        }
                    },
                    {
                        key: 'dd',
                        regex: '[0-2][0-9]{1}|3[0-1]{1}',
                        apply: function(value) {
                            this.date = +value;
                        },
                        formatter: function(date) {
                            return dateFilter(date, 'dd');
                        }
                    },
                    {
                        key: 'd',
                        regex: '[1-2]?[0-9]{1}|3[0-1]{1}',
                        apply: function(value) {
                            this.date = +value;
                        },
                        formatter: function(date) {
                            return dateFilter(date, 'd');
                        }
                    },
                    {
                        key: 'EEEE',
                        regex: $locale.DATETIME_FORMATS.DAY.join('|'),
                        formatter: function(date) {
                            return dateFilter(date, 'EEEE');
                        }
                    },
                    {
                        key: 'EEE',
                        regex: $locale.DATETIME_FORMATS.SHORTDAY.join('|'),
                        formatter: function(date) {
                            return dateFilter(date, 'EEE');
                        }
                    },
                    {
                        key: 'HH',
                        regex: '(?:0|1)[0-9]|2[0-3]',
                        apply: function(value) {
                            this.hours = +value;
                        },
                        formatter: function(date) {
                            return dateFilter(date, 'HH');
                        }
                    },
                    {
                        key: 'hh',
                        regex: '0[0-9]|1[0-2]',
                        apply: function(value) {
                            this.hours = +value;
                        },
                        formatter: function(date) {
                            return dateFilter(date, 'hh');
                        }
                    },
                    {
                        key: 'H',
                        regex: '1?[0-9]|2[0-3]',
                        apply: function(value) {
                            this.hours = +value;
                        },
                        formatter: function(date) {
                            return dateFilter(date, 'H');
                        }
                    },
                    {
                        key: 'h',
                        regex: '[0-9]|1[0-2]',
                        apply: function(value) {
                            this.hours = +value;
                        },
                        formatter: function(date) {
                            return dateFilter(date, 'h');
                        }
                    },
                    {
                        key: 'mm',
                        regex: '[0-5][0-9]',
                        apply: function(value) {
                            this.minutes = +value;
                        },
                        formatter: function(date) {
                            return dateFilter(date, 'mm');
                        }
                    },
                    {
                        key: 'm',
                        regex: '[0-9]|[1-5][0-9]',
                        apply: function(value) {
                            this.minutes = +value;
                        },
                        formatter: function(date) {
                            return dateFilter(date, 'm');
                        }
                    },
                    {
                        key: 'sss',
                        regex: '[0-9][0-9][0-9]',
                        apply: function(value) {
                            this.milliseconds = +value;
                        },
                        formatter: function(date) {
                            return dateFilter(date, 'sss');
                        }
                    },
                    {
                        key: 'ss',
                        regex: '[0-5][0-9]',
                        apply: function(value) {
                            this.seconds = +value;
                        },
                        formatter: function(date) {
                            return dateFilter(date, 'ss');
                        }
                    },
                    {
                        key: 's',
                        regex: '[0-9]|[1-5][0-9]',
                        apply: function(value) {
                            this.seconds = +value;
                        },
                        formatter: function(date) {
                            return dateFilter(date, 's');
                        }
                    },
                    {
                        key: 'a',
                        regex: $locale.DATETIME_FORMATS.AMPMS.join('|'),
                        apply: function(value) {
                            if (this.hours === 12) {
                                this.hours = 0;
                            }
                            if (value === 'PM') {
                                this.hours += 12;
                            }
                        },
                        formatter: function(date) {
                            return dateFilter(date, 'a');
                        }
                    },
                    {
                        key: 'Z',
                        regex: '[+-]\\d{4}',
                        apply: function(value) {
                            var matches = value.match(/([+-])(\d{2})(\d{2})/),
                                sign = matches[1],
                                hours = matches[2],
                                minutes = matches[3];
                            this.hours += toInt(sign + hours);
                            this.minutes += toInt(sign + minutes);
                        },
                        formatter: function(date) {
                            return dateFilter(date, 'Z');
                        }
                    },
                    {
                        key: 'ww',
                        regex: '[0-4][0-9]|5[0-3]',
                        formatter: function(date) {
                            return dateFilter(date, 'ww');
                        }
                    },
                    {
                        key: 'w',
                        regex: '[0-9]|[1-4][0-9]|5[0-3]',
                        formatter: function(date) {
                            return dateFilter(date, 'w');
                        }
                    },
                    {
                        key: 'GGGG',
                        regex: $locale.DATETIME_FORMATS.ERANAMES.join('|').replace(/\s/g, '\\s'),
                        formatter: function(date) {
                            return dateFilter(date, 'GGGG');
                        }
                    },
                    {
                        key: 'GGG',
                        regex: $locale.DATETIME_FORMATS.ERAS.join('|'),
                        formatter: function(date) {
                            return dateFilter(date, 'GGG');
                        }
                    },
                    {
                        key: 'GG',
                        regex: $locale.DATETIME_FORMATS.ERAS.join('|'),
                        formatter: function(date) {
                            return dateFilter(date, 'GG');
                        }
                    },
                    {
                        key: 'G',
                        regex: $locale.DATETIME_FORMATS.ERAS.join('|'),
                        formatter: function(date) {
                            return dateFilter(date, 'G');
                        }
                    }
                ];
            };
            this.init();
    
            function createParser(format, func) {
                var map = [],
                    regex = format.split('');
                var quoteIndex = format.indexOf('\'');
                if (quoteIndex > -1) {
                    var inLiteral = false;
                    format = format.split('');
                    for (var i = quoteIndex; i < format.length; i++) {
                        if (inLiteral) {
                            if (format[i] === '\'') {
                                if (i + 1 < format.length && format[i + 1] === '\'') {
                                    format[i + 1] = '$';
                                    regex[i + 1] = '';
                                } else {
                                    regex[i] = '';
                                    inLiteral = false;
                                }
                            }
                            format[i] = '$';
                        } else {
                            if (format[i] === '\'') {
                                format[i] = '$';
                                regex[i] = '';
                                inLiteral = true;
                            }
                        }
                    }
                    format = format.join('');
                }
                angular.forEach(formatCodeToRegex, function(data) {
                    var index = format.indexOf(data.key);
                    if (index > -1) {
                        format = format.split('');
                        regex[index] = '(' + data.regex + ')';
                        format[index] = '$';
                        for (var i = index + 1, n = index + data.key.length; i < n; i++) {
                            regex[i] = '';
                            format[i] = '$';
                        }
                        format = format.join('');
                        map.push({
                            index: index,
                            key: data.key,
                            apply: data[func],
                            matcher: data.regex
                        });
                    }
                });
                return {
                    regex: new RegExp('^' + regex.join('') + '$'),
                    map: orderByFilter(map, 'index')
                };
            }
            this.filter = function(date, format) {
                if (!angular.isDate(date) || isNaN(date) || !format) {
                    return '';
                }
                format = $locale.DATETIME_FORMATS[format] || format;
                if ($locale.id !== localeId) {
                    this.init();
                }
                if (!this.formatters[format]) {
                    this.formatters[format] = createParser(format, 'formatter');
                }
                var parser = this.formatters[format],
                    map = parser.map;
                var _format = format;
                return map.reduce(function(str, mapper, i) {
                    var match = _format.match(new RegExp('(.*)' + mapper.key));
                    if (match && angular.isString(match[1])) {
                        str += match[1];
                        _format = _format.replace(match[1] + mapper.key, '');
                    }
                    if (mapper.apply) {
                        return str + mapper.apply.call(null, date);
                    }
                    return str;
                }, '');
            };
            this.parse = function(input, format, baseDate) {
                if (!angular.isString(input) || !format) {
                    return input;
                }
                format = $locale.DATETIME_FORMATS[format] || format;
                format = format.replace(SPECIAL_CHARACTERS_REGEXP, '\\$&');
                if ($locale.id !== localeId) {
                    this.init();
                }
                if (!this.parsers[format]) {
                    this.parsers[format] = createParser(format, 'apply');
                }
                var parser = this.parsers[format],
                    regex = parser.regex,
                    map = parser.map,
                    results = input.match(regex),
                    tzOffset = false;
                if (results && results.length) {
                    var fields, dt;
                    if (angular.isDate(baseDate) && !isNaN(baseDate.getTime())) {
                        fields = {
                            year: baseDate.getFullYear(),
                            month: baseDate.getMonth(),
                            date: baseDate.getDate(),
                            hours: baseDate.getHours(),
                            minutes: baseDate.getMinutes(),
                            seconds: baseDate.getSeconds(),
                            milliseconds: baseDate.getMilliseconds()
                        };
                    } else {
                        if (baseDate) {
                            $log.warn('dateparser:', 'baseDate is not a valid date');
                        }
                        fields = {
                            year: 1900,
                            month: 0,
                            date: 1,
                            hours: 0,
                            minutes: 0,
                            seconds: 0,
                            milliseconds: 0
                        };
                    }
                    for (var i = 1, n = results.length; i < n; i++) {
                        var mapper = map[i - 1];
                        if (mapper.matcher === 'Z') {
                            tzOffset = true;
                        }
                        if (mapper.apply) {
                            mapper.apply.call(fields, results[i]);
                        }
                    }
                    var datesetter = tzOffset ? Date.prototype.setUTCFullYear :
                        Date.prototype.setFullYear;
                    var timesetter = tzOffset ? Date.prototype.setUTCHours :
                        Date.prototype.setHours;
                    if (isValid(fields.year, fields.month, fields.date)) {
                        if (angular.isDate(baseDate) && !isNaN(baseDate.getTime()) && !tzOffset) {
                            dt = new Date(baseDate);
                            datesetter.call(dt, fields.year, fields.month, fields.date);
                            timesetter.call(dt, fields.hours, fields.minutes,
                                fields.seconds, fields.milliseconds);
                        } else {
                            dt = new Date(0);
                            datesetter.call(dt, fields.year, fields.month, fields.date);
                            timesetter.call(dt, fields.hours || 0, fields.minutes || 0,
                                fields.seconds || 0, fields.milliseconds || 0);
                        }
                    }
                    return dt;
                }
            };
    
            function isValid(year, month, date) {
                if (date < 1) {
                    return false;
                }
                if (month === 1 && date > 28) {
                    return date === 29 && (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0);
                }
                if (month === 3 || month === 5 || month === 8 || month === 10) {
                    return date < 31;
                }
                return true;
            }
    
            function toInt(str) {
                return parseInt(str, 10);
            }
            this.toTimezone = toTimezone;
            this.fromTimezone = fromTimezone;
            this.timezoneToOffset = timezoneToOffset;
            this.addDateMinutes = addDateMinutes;
            this.convertTimezoneToLocal = convertTimezoneToLocal;
    
            function toTimezone(date, timezone) {
                return date && timezone ? convertTimezoneToLocal(date, timezone) : date;
            }
    
            function fromTimezone(date, timezone) {
                return date && timezone ? convertTimezoneToLocal(date, timezone, true) : date;
            }
    
            function timezoneToOffset(timezone, fallback) {
                var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;
                return isNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;
            }
    
            function addDateMinutes(date, minutes) {
                date = new Date(date.getTime());
                date.setMinutes(date.getMinutes() + minutes);
                return date;
            }
    
            function convertTimezoneToLocal(date, timezone, reverse) {
                reverse = reverse ? -1 : 1;
                var timezoneOffset = timezoneToOffset(timezone, date.getTimezoneOffset());
                return addDateMinutes(date, reverse * (timezoneOffset - date.getTimezoneOffset()));
            }
        }]);
    angular.module('ui.bootstrap.isClass', [])
        .directive('uibIsClass', [
            '$animate',
            function($animate) {
                var ON_REGEXP = /^\s*([\s\S]+?)\s+on\s+([\s\S]+?)\s*$/;
                var IS_REGEXP = /^\s*([\s\S]+?)\s+for\s+([\s\S]+?)\s*$/;
                var dataPerTracked = {};
                return {
                    restrict: 'A',
                    compile: function(tElement, tAttrs) {
                        var linkedScopes = [];
                        var instances = [];
                        var expToData = {};
                        var lastActivated = null;
                        var onExpMatches = tAttrs.uibIsClass.match(ON_REGEXP);
                        var onExp = onExpMatches[2];
                        var expsStr = onExpMatches[1];
                        var exps = expsStr.split(',');
                        return linkFn;
    
                        function linkFn(scope, element, attrs) {
                            linkedScopes.push(scope);
                            instances.push({
                                scope: scope,
                                element: element
                            });
                            exps.forEach(function(exp, k) {
                                addForExp(exp, scope);
                            });
                            scope.$on('$destroy', removeScope);
                        }
    
                        function addForExp(exp, scope) {
                            var matches = exp.match(IS_REGEXP);
                            var clazz = scope.$eval(matches[1]);
                            var compareWithExp = matches[2];
                            var data = expToData[exp];
                            if (!data) {
                                var watchFn = function(compareWithVal) {
                                    var newActivated = null;
                                    instances.some(function(instance) {
                                        var thisVal = instance.scope.$eval(onExp);
                                        if (thisVal === compareWithVal) {
                                            newActivated = instance;
                                            return true;
                                        }
                                    });
                                    if (data.lastActivated !== newActivated) {
                                        if (data.lastActivated) {
                                            $animate.removeClass(data.lastActivated.element, clazz);
                                        }
                                        if (newActivated) {
                                            $animate.addClass(newActivated.element, clazz);
                                        }
                                        data.lastActivated = newActivated;
                                    }
                                };
                                expToData[exp] = data = {
                                    lastActivated: null,
                                    scope: scope,
                                    watchFn: watchFn,
                                    compareWithExp: compareWithExp,
                                    watcher: scope.$watch(compareWithExp, watchFn)
                                };
                            }
                            data.watchFn(scope.$eval(compareWithExp));
                        }
    
                        function removeScope(e) {
                            var removedScope = e.targetScope;
                            var index = linkedScopes.indexOf(removedScope);
                            linkedScopes.splice(index, 1);
                            instances.splice(index, 1);
                            if (linkedScopes.length) {
                                var newWatchScope = linkedScopes[0];
                                angular.forEach(expToData, function(data) {
                                    if (data.scope === removedScope) {
                                        data.watcher = newWatchScope.$watch(data.compareWithExp, data.watchFn);
                                        data.scope = newWatchScope;
                                    }
                                });
                            } else {
                                expToData = {};
                            }
                        }
                    }
                };
            }
        ]);
    angular.module('ui.bootstrap.position', [])
        .factory('$uibPosition', ['$document', '$window', function($document, $window) {
            var SCROLLBAR_WIDTH;
            var OVERFLOW_REGEX = {
                normal: /(auto|scroll)/,
                hidden: /(auto|scroll|hidden)/
            };
            var PLACEMENT_REGEX = {
                auto: /\s?auto?\s?/i,
                primary: /^(top|bottom|left|right)$/,
                secondary: /^(top|bottom|left|right|center)$/,
                vertical: /^(top|bottom)$/
            };
            return {
                getRawNode: function(elem) {
                    return elem[0] || elem;
                },
                parseStyle: function(value) {
                    value = parseFloat(value);
                    return isFinite(value) ? value : 0;
                },
                offsetParent: function(elem) {
                    elem = this.getRawNode(elem);
                    var offsetParent = elem.offsetParent || $document[0].documentElement;
    
                    function isStaticPositioned(el) {
                        return ($window.getComputedStyle(el).position || 'static') === 'static';
                    }
                    while (offsetParent && offsetParent !== $document[0].documentElement && isStaticPositioned(offsetParent)) {
                        offsetParent = offsetParent.offsetParent;
                    }
                    return offsetParent || $document[0].documentElement;
                },
                scrollbarWidth: function() {
                    if (angular.isUndefined(SCROLLBAR_WIDTH)) {
                        var scrollElem = angular.element('<div style="position: absolute; top: -9999px; width: 50px; height: 50px; overflow: scroll;"></div>');
                        $document.find('body').append(scrollElem);
                        SCROLLBAR_WIDTH = scrollElem[0].offsetWidth - scrollElem[0].clientWidth;
                        SCROLLBAR_WIDTH = isFinite(SCROLLBAR_WIDTH) ? SCROLLBAR_WIDTH : 0;
                        scrollElem.remove();
                    }
                    return SCROLLBAR_WIDTH;
                },
                scrollParent: function(elem, includeHidden) {
                    elem = this.getRawNode(elem);
                    var overflowRegex = includeHidden ? OVERFLOW_REGEX.hidden : OVERFLOW_REGEX.normal;
                    var documentEl = $document[0].documentElement;
                    var elemStyle = $window.getComputedStyle(elem);
                    var excludeStatic = elemStyle.position === 'absolute';
                    var scrollParent = elem.parentElement || documentEl;
                    if (scrollParent === documentEl || elemStyle.position === 'fixed') {
                        return documentEl;
                    }
                    while (scrollParent.parentElement && scrollParent !== documentEl) {
                        var spStyle = $window.getComputedStyle(scrollParent);
                        if (excludeStatic && spStyle.position !== 'static') {
                            excludeStatic = false;
                        }
                        if (!excludeStatic && overflowRegex.test(spStyle.overflow + spStyle.overflowY + spStyle.overflowX)) {
                            break;
                        }
                        scrollParent = scrollParent.parentElement;
                    }
                    return scrollParent;
                },
                position: function(elem, includeMagins) {
                    elem = this.getRawNode(elem);
                    var elemOffset = this.offset(elem);
                    if (includeMagins) {
                        var elemStyle = $window.getComputedStyle(elem);
                        elemOffset.top -= this.parseStyle(elemStyle.marginTop);
                        elemOffset.left -= this.parseStyle(elemStyle.marginLeft);
                    }
                    var parent = this.offsetParent(elem);
                    var parentOffset = {
                        top: 0,
                        left: 0
                    };
                    if (parent !== $document[0].documentElement) {
                        parentOffset = this.offset(parent);
                        parentOffset.top += parent.clientTop - parent.scrollTop;
                        parentOffset.left += parent.clientLeft - parent.scrollLeft;
                    }
                    return {
                        width: Math.round(angular.isNumber(elemOffset.width) ? elemOffset.width : elem.offsetWidth),
                        height: Math.round(angular.isNumber(elemOffset.height) ? elemOffset.height : elem.offsetHeight),
                        top: Math.round(elemOffset.top - parentOffset.top),
                        left: Math.round(elemOffset.left - parentOffset.left)
                    };
                },
                offset: function(elem) {
                    elem = this.getRawNode(elem);
                    var elemBCR = elem.getBoundingClientRect();
                    return {
                        width: Math.round(angular.isNumber(elemBCR.width) ? elemBCR.width : elem.offsetWidth),
                        height: Math.round(angular.isNumber(elemBCR.height) ? elemBCR.height : elem.offsetHeight),
                        top: Math.round(elemBCR.top + ($window.pageYOffset || $document[0].documentElement.scrollTop)),
                        left: Math.round(elemBCR.left + ($window.pageXOffset || $document[0].documentElement.scrollLeft))
                    };
                },
                viewportOffset: function(elem, useDocument, includePadding) {
                    elem = this.getRawNode(elem);
                    includePadding = includePadding !== false ? true : false;
                    var elemBCR = elem.getBoundingClientRect();
                    var offsetBCR = {
                        top: 0,
                        left: 0,
                        bottom: 0,
                        right: 0
                    };
                    var offsetParent = useDocument ? $document[0].documentElement : this.scrollParent(elem);
                    var offsetParentBCR = offsetParent.getBoundingClientRect();
                    offsetBCR.top = offsetParentBCR.top + offsetParent.clientTop;
                    offsetBCR.left = offsetParentBCR.left + offsetParent.clientLeft;
                    if (offsetParent === $document[0].documentElement) {
                        offsetBCR.top += $window.pageYOffset;
                        offsetBCR.left += $window.pageXOffset;
                    }
                    offsetBCR.bottom = offsetBCR.top + offsetParent.clientHeight;
                    offsetBCR.right = offsetBCR.left + offsetParent.clientWidth;
                    if (includePadding) {
                        var offsetParentStyle = $window.getComputedStyle(offsetParent);
                        offsetBCR.top += this.parseStyle(offsetParentStyle.paddingTop);
                        offsetBCR.bottom -= this.parseStyle(offsetParentStyle.paddingBottom);
                        offsetBCR.left += this.parseStyle(offsetParentStyle.paddingLeft);
                        offsetBCR.right -= this.parseStyle(offsetParentStyle.paddingRight);
                    }
                    return {
                        top: Math.round(elemBCR.top - offsetBCR.top),
                        bottom: Math.round(offsetBCR.bottom - elemBCR.bottom),
                        left: Math.round(elemBCR.left - offsetBCR.left),
                        right: Math.round(offsetBCR.right - elemBCR.right)
                    };
                },
                parsePlacement: function(placement) {
                    var autoPlace = PLACEMENT_REGEX.auto.test(placement);
                    if (autoPlace) {
                        placement = placement.replace(PLACEMENT_REGEX.auto, '');
                    }
                    placement = placement.split('-');
                    placement[0] = placement[0] || 'top';
                    if (!PLACEMENT_REGEX.primary.test(placement[0])) {
                        placement[0] = 'top';
                    }
                    placement[1] = placement[1] || 'center';
                    if (!PLACEMENT_REGEX.secondary.test(placement[1])) {
                        placement[1] = 'center';
                    }
                    if (autoPlace) {
                        placement[2] = true;
                    } else {
                        placement[2] = false;
                    }
                    return placement;
                },
                positionElements: function(hostElem, targetElem, placement, appendToBody) {
                    hostElem = this.getRawNode(hostElem);
                    targetElem = this.getRawNode(targetElem);
                    var targetWidth = angular.isDefined(targetElem.offsetWidth) ? targetElem.offsetWidth : targetElem.prop('offsetWidth');
                    var targetHeight = angular.isDefined(targetElem.offsetHeight) ? targetElem.offsetHeight : targetElem.prop('offsetHeight');
                    placement = this.parsePlacement(placement);
                    var hostElemPos = appendToBody ? this.offset(hostElem) : this.position(hostElem);
                    var targetElemPos = {
                        top: 0,
                        left: 0,
                        placement: ''
                    };
                    if (placement[2]) {
                        var viewportOffset = this.viewportOffset(hostElem);
                        var targetElemStyle = $window.getComputedStyle(targetElem);
                        var adjustedSize = {
                            width: targetWidth + Math.round(Math.abs(this.parseStyle(targetElemStyle.marginLeft) + this.parseStyle(targetElemStyle.marginRight))),
                            height: targetHeight + Math.round(Math.abs(this.parseStyle(targetElemStyle.marginTop) + this.parseStyle(targetElemStyle.marginBottom)))
                        };
                        placement[0] = placement[0] === 'top' && adjustedSize.height > viewportOffset.top && adjustedSize.height <= viewportOffset.bottom ? 'bottom' :
                            placement[0] === 'bottom' && adjustedSize.height > viewportOffset.bottom && adjustedSize.height <= viewportOffset.top ? 'top' :
                            placement[0] === 'left' && adjustedSize.width > viewportOffset.left && adjustedSize.width <= viewportOffset.right ? 'right' :
                            placement[0] === 'right' && adjustedSize.width > viewportOffset.right && adjustedSize.width <= viewportOffset.left ? 'left' :
                            placement[0];
                        placement[1] = placement[1] === 'top' && adjustedSize.height - hostElemPos.height > viewportOffset.bottom && adjustedSize.height - hostElemPos.height <= viewportOffset.top ? 'bottom' :
                            placement[1] === 'bottom' && adjustedSize.height - hostElemPos.height > viewportOffset.top && adjustedSize.height - hostElemPos.height <= viewportOffset.bottom ? 'top' :
                            placement[1] === 'left' && adjustedSize.width - hostElemPos.width > viewportOffset.right && adjustedSize.width - hostElemPos.width <= viewportOffset.left ? 'right' :
                            placement[1] === 'right' && adjustedSize.width - hostElemPos.width > viewportOffset.left && adjustedSize.width - hostElemPos.width <= viewportOffset.right ? 'left' :
                            placement[1];
                        if (placement[1] === 'center') {
                            if (PLACEMENT_REGEX.vertical.test(placement[0])) {
                                var xOverflow = hostElemPos.width / 2 - targetWidth / 2;
                                if (viewportOffset.left + xOverflow < 0 && adjustedSize.width - hostElemPos.width <= viewportOffset.right) {
                                    placement[1] = 'left';
                                } else if (viewportOffset.right + xOverflow < 0 && adjustedSize.width - hostElemPos.width <= viewportOffset.left) {
                                    placement[1] = 'right';
                                }
                            } else {
                                var yOverflow = hostElemPos.height / 2 - adjustedSize.height / 2;
                                if (viewportOffset.top + yOverflow < 0 && adjustedSize.height - hostElemPos.height <= viewportOffset.bottom) {
                                    placement[1] = 'top';
                                } else if (viewportOffset.bottom + yOverflow < 0 && adjustedSize.height - hostElemPos.height <= viewportOffset.top) {
                                    placement[1] = 'bottom';
                                }
                            }
                        }
                    }
                    switch (placement[0]) {
                        case 'top':
                            targetElemPos.top = hostElemPos.top - targetHeight;
                            break;
                        case 'bottom':
                            targetElemPos.top = hostElemPos.top + hostElemPos.height;
                            break;
                        case 'left':
                            targetElemPos.left = hostElemPos.left - targetWidth;
                            break;
                        case 'right':
                            targetElemPos.left = hostElemPos.left + hostElemPos.width;
                            break;
                    }
                    switch (placement[1]) {
                        case 'top':
                            targetElemPos.top = hostElemPos.top;
                            break;
                        case 'bottom':
                            targetElemPos.top = hostElemPos.top + hostElemPos.height - targetHeight;
                            break;
                        case 'left':
                            targetElemPos.left = hostElemPos.left;
                            break;
                        case 'right':
                            targetElemPos.left = hostElemPos.left + hostElemPos.width - targetWidth;
                            break;
                        case 'center':
                            if (PLACEMENT_REGEX.vertical.test(placement[0])) {
                                targetElemPos.left = hostElemPos.left + hostElemPos.width / 2 - targetWidth / 2;
                            } else {
                                targetElemPos.top = hostElemPos.top + hostElemPos.height / 2 - targetHeight / 2;
                            }
                            break;
                    }
                    targetElemPos.top = Math.round(targetElemPos.top);
                    targetElemPos.left = Math.round(targetElemPos.left);
                    targetElemPos.placement = placement[1] === 'center' ? placement[0] : placement[0] + '-' + placement[1];
                    return targetElemPos;
                },
                positionArrow: function(elem, placement) {
                    elem = this.getRawNode(elem);
                    var innerElem = elem.querySelector('.tooltip-inner, .popover-inner');
                    if (!innerElem) {
                        return;
                    }
                    var isTooltip = angular.element(innerElem).hasClass('tooltip-inner');
                    var arrowElem = isTooltip ? elem.querySelector('.tooltip-arrow') : elem.querySelector('.arrow');
                    if (!arrowElem) {
                        return;
                    }
                    placement = this.parsePlacement(placement);
                    if (placement[1] === 'center') {
                        angular.element(arrowElem).css({
                            top: '',
                            bottom: '',
                            right: '',
                            left: '',
                            margin: ''
                        });
                        return;
                    }
                    var borderProp = 'border-' + placement[0] + '-width';
                    var borderWidth = $window.getComputedStyle(arrowElem)[borderProp];
                    var borderRadiusProp = 'border-';
                    if (PLACEMENT_REGEX.vertical.test(placement[0])) {
                        borderRadiusProp += placement[0] + '-' + placement[1];
                    } else {
                        borderRadiusProp += placement[1] + '-' + placement[0];
                    }
                    borderRadiusProp += '-radius';
                    var borderRadius = $window.getComputedStyle(isTooltip ? innerElem : elem)[borderRadiusProp];
                    var arrowCss = {
                        top: 'auto',
                        bottom: 'auto',
                        left: 'auto',
                        right: 'auto',
                        margin: 0
                    };
                    switch (placement[0]) {
                        case 'top':
                            arrowCss.bottom = isTooltip ? '0' : '-' + borderWidth;
                            break;
                        case 'bottom':
                            arrowCss.top = isTooltip ? '0' : '-' + borderWidth;
                            break;
                        case 'left':
                            arrowCss.right = isTooltip ? '0' : '-' + borderWidth;
                            break;
                        case 'right':
                            arrowCss.left = isTooltip ? '0' : '-' + borderWidth;
                            break;
                    }
                    arrowCss[placement[1]] = borderRadius;
                    angular.element(arrowElem).css(arrowCss);
                }
            };
        }]);
    angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootstrap.isClass', 'ui.bootstrap.position'])
        .value('$datepickerSuppressError', false)
        .constant('uibDatepickerConfig', {
            datepickerMode: 'day',
            formatDay: 'dd',
            formatMonth: 'MMMM',
            formatYear: 'yyyy',
            formatDayHeader: 'EEE',
            formatDayTitle: 'MMMM yyyy',
            formatMonthTitle: 'yyyy',
            maxDate: null,
            maxMode: 'year',
            minDate: null,
            minMode: 'day',
            ngModelOptions: {},
            shortcutPropagation: false,
            showWeeks: true,
            yearColumns: 5,
            yearRows: 4
        })
        .controller('UibDatepickerController', ['$scope', '$attrs', '$parse', '$interpolate', '$locale', '$log', 'dateFilter', 'uibDatepickerConfig', '$datepickerSuppressError', 'uibDateParser',
            function($scope, $attrs, $parse, $interpolate, $locale, $log, dateFilter, datepickerConfig, $datepickerSuppressError, dateParser) {
                var self = this,
                    ngModelCtrl = {
                        $setViewValue: angular.noop
                    },
                    ngModelOptions = {},
                    watchListeners = [];
                this.modes = ['day', 'month', 'year'];
                if ($attrs.datepickerOptions) {
                    angular.forEach([
                        'formatDay',
                        'formatDayHeader',
                        'formatDayTitle',
                        'formatMonth',
                        'formatMonthTitle',
                        'formatYear',
                        'initDate',
                        'maxDate',
                        'maxMode',
                        'minDate',
                        'minMode',
                        'showWeeks',
                        'shortcutPropagation',
                        'startingDay',
                        'yearColumns',
                        'yearRows'
                    ], function(key) {
                        switch (key) {
                            case 'formatDay':
                            case 'formatDayHeader':
                            case 'formatDayTitle':
                            case 'formatMonth':
                            case 'formatMonthTitle':
                            case 'formatYear':
                                self[key] = angular.isDefined($scope.datepickerOptions[key]) ? $interpolate($scope.datepickerOptions[key])($scope.$parent) : datepickerConfig[key];
                                break;
                            case 'showWeeks':
                            case 'shortcutPropagation':
                            case 'yearColumns':
                            case 'yearRows':
                                self[key] = angular.isDefined($scope.datepickerOptions[key]) ?
                                    $scope.datepickerOptions[key] : datepickerConfig[key];
                                break;
                            case 'startingDay':
                                if (angular.isDefined($scope.datepickerOptions.startingDay)) {
                                    self.startingDay = $scope.datepickerOptions.startingDay;
                                } else if (angular.isNumber(datepickerConfig.startingDay)) {
                                    self.startingDay = datepickerConfig.startingDay;
                                } else {
                                    self.startingDay = ($locale.DATETIME_FORMATS.FIRSTDAYOFWEEK + 8) % 7;
                                }
                                break;
                            case 'maxDate':
                            case 'minDate':
                                if ($scope.datepickerOptions[key]) {
                                    $scope.$watch(function() {
                                        return $scope.datepickerOptions[key];
                                    }, function(value) {
                                        if (value) {
                                            if (angular.isDate(value)) {
                                                self[key] = dateParser.fromTimezone(new Date(value), ngModelOptions.timezone);
                                            } else {
                                                self[key] = new Date(dateFilter(value, 'medium'));
                                            }
                                        } else {
                                            self[key] = null;
                                        }
                                        self.refreshView();
                                    });
                                } else {
                                    self[key] = datepickerConfig[key] ? dateParser.fromTimezone(new Date(datepickerConfig[key]), ngModelOptions.timezone) : null;
                                }
                                break;
                            case 'maxMode':
                            case 'minMode':
                                if ($scope.datepickerOptions[key]) {
                                    $scope.$watch(function() {
                                        return $scope.datepickerOptions[key];
                                    }, function(value) {
                                        self[key] = $scope[key] = angular.isDefined(value) ? value : datepickerOptions[key];
                                        if (key === 'minMode' && self.modes.indexOf($scope.datepickerMode) < self.modes.indexOf(self[key]) ||
                                            key === 'maxMode' && self.modes.indexOf($scope.datepickerMode) > self.modes.indexOf(self[key])) {
                                            $scope.datepickerMode = self[key];
                                        }
                                    });
                                } else {
                                    self[key] = $scope[key] = datepickerConfig[key] || null;
                                }
                                break;
                            case 'initDate':
                                if ($scope.datepickerOptions.initDate) {
                                    this.activeDate = dateParser.fromTimezone($scope.datepickerOptions.initDate, ngModelOptions.timezone) || new Date();
                                    $scope.$watch(function() {
                                        return $scope.datepickerOptions.initDate;
                                    }, function(initDate) {
                                        if (initDate && (ngModelCtrl.$isEmpty(ngModelCtrl.$modelValue) || ngModelCtrl.$invalid)) {
                                            self.activeDate = dateParser.fromTimezone(initDate, ngModelOptions.timezone);
                                            self.refreshView();
                                        }
                                    });
                                } else {
                                    this.activeDate = new Date();
                                }
                        }
                    });
                } else {
                    angular.forEach(['formatDay', 'formatMonth', 'formatYear', 'formatDayHeader', 'formatDayTitle', 'formatMonthTitle'], function(key) {
                        self[key] = angular.isDefined($attrs[key]) ? $interpolate($attrs[key])($scope.$parent) : datepickerConfig[key];
                    });
                    angular.forEach(['showWeeks', 'yearRows', 'yearColumns', 'shortcutPropagation'], function(key) {
                        self[key] = angular.isDefined($attrs[key]) ?
                            $scope.$parent.$eval($attrs[key]) : datepickerConfig[key];
                    });
                    if (angular.isDefined($attrs.startingDay)) {
                        self.startingDay = $scope.$parent.$eval($attrs.startingDay);
                    } else if (angular.isNumber(datepickerConfig.startingDay)) {
                        self.startingDay = datepickerConfig.startingDay;
                    } else {
                        self.startingDay = ($locale.DATETIME_FORMATS.FIRSTDAYOFWEEK + 8) % 7;
                    }
                    angular.forEach(['minDate', 'maxDate'], function(key) {
                        if ($attrs[key]) {
                            watchListeners.push($scope.$parent.$watch($attrs[key], function(value) {
                                if (value) {
                                    if (angular.isDate(value)) {
                                        self[key] = dateParser.fromTimezone(new Date(value), ngModelOptions.timezone);
                                    } else {
                                        self[key] = new Date(dateFilter(value, 'medium'));
                                    }
                                } else {
                                    self[key] = null;
                                }
                                self.refreshView();
                            }));
                        } else {
                            self[key] = datepickerConfig[key] ? dateParser.fromTimezone(new Date(datepickerConfig[key]), ngModelOptions.timezone) : null;
                        }
                    });
                    angular.forEach(['minMode', 'maxMode'], function(key) {
                        if ($attrs[key]) {
                            watchListeners.push($scope.$parent.$watch($attrs[key], function(value) {
                                self[key] = $scope[key] = angular.isDefined(value) ? value : $attrs[key];
                                if (key === 'minMode' && self.modes.indexOf($scope.datepickerMode) < self.modes.indexOf(self[key]) ||
                                    key === 'maxMode' && self.modes.indexOf($scope.datepickerMode) > self.modes.indexOf(self[key])) {
                                    $scope.datepickerMode = self[key];
                                }
                            }));
                        } else {
                            self[key] = $scope[key] = datepickerConfig[key] || null;
                        }
                    });
                    if (angular.isDefined($attrs.initDate)) {
                        this.activeDate = dateParser.fromTimezone($scope.$parent.$eval($attrs.initDate), ngModelOptions.timezone) || new Date();
                        watchListeners.push($scope.$parent.$watch($attrs.initDate, function(initDate) {
                            if (initDate && (ngModelCtrl.$isEmpty(ngModelCtrl.$modelValue) || ngModelCtrl.$invalid)) {
                                self.activeDate = dateParser.fromTimezone(initDate, ngModelOptions.timezone);
                                self.refreshView();
                            }
                        }));
                    } else {
                        this.activeDate = new Date();
                    }
                }
                $scope.datepickerMode = $scope.datepickerMode || datepickerConfig.datepickerMode;
                $scope.uniqueId = 'datepicker-' + $scope.$id + '-' + Math.floor(Math.random() * 10000);
                $scope.disabled = angular.isDefined($attrs.disabled) || false;
                if (angular.isDefined($attrs.ngDisabled)) {
                    watchListeners.push($scope.$parent.$watch($attrs.ngDisabled, function(disabled) {
                        $scope.disabled = disabled;
                        self.refreshView();
                    }));
                }
                $scope.isActive = function(dateObject) {
                    if (self.compare(dateObject.date, self.activeDate) === 0) {
                        $scope.activeDateId = dateObject.uid;
                        return true;
                    }
                    return false;
                };
                this.init = function(ngModelCtrl_) {
                    ngModelCtrl = ngModelCtrl_;
                    ngModelOptions = ngModelCtrl_.$options || datepickerConfig.ngModelOptions;
                    if (ngModelCtrl.$modelValue) {
                        this.activeDate = ngModelCtrl.$modelValue;
                    }
                    ngModelCtrl.$render = function() {
                        self.render();
                    };
                };
                this.render = function() {
                    if (ngModelCtrl.$viewValue) {
                        var date = new Date(ngModelCtrl.$viewValue),
                            isValid = !isNaN(date);
                        if (isValid) {
                            this.activeDate = dateParser.fromTimezone(date, ngModelOptions.timezone);
                        } else if (!$datepickerSuppressError) {
                            $log.error('Datepicker directive: "ng-model" value must be a Date object');
                        }
                    }
                    this.refreshView();
                };
                this.refreshView = function() {
                    if (this.element) {
                        $scope.selectedDt = null;
                        this._refreshView();
                        if ($scope.activeDt) {
                            $scope.activeDateId = $scope.activeDt.uid;
                        }
                        var date = ngModelCtrl.$viewValue ? new Date(ngModelCtrl.$viewValue) : null;
                        date = dateParser.fromTimezone(date, ngModelOptions.timezone);
                        ngModelCtrl.$setValidity('dateDisabled', !date ||
                            this.element && !this.isDisabled(date));
                    }
                };
                this.createDateObject = function(date, format) {
                    var model = ngModelCtrl.$viewValue ? new Date(ngModelCtrl.$viewValue) : null;
                    model = dateParser.fromTimezone(model, ngModelOptions.timezone);
                    var dt = {
                        date: date,
                        label: dateParser.filter(date, format),
                        selected: model && this.compare(date, model) === 0,
                        disabled: this.isDisabled(date),
                        current: this.compare(date, new Date()) === 0,
                        customClass: this.customClass(date) || null
                    };
                    if (model && this.compare(date, model) === 0) {
                        $scope.selectedDt = dt;
                    }
                    if (self.activeDate && this.compare(dt.date, self.activeDate) === 0) {
                        $scope.activeDt = dt;
                    }
                    return dt;
                };
                this.isDisabled = function(date) {
                    return $scope.disabled ||
                        this.minDate && this.compare(date, this.minDate) < 0 ||
                        this.maxDate && this.compare(date, this.maxDate) > 0 ||
                        $attrs.dateDisabled && $scope.dateDisabled({
                            date: date,
                            mode: $scope.datepickerMode
                        });
                };
                this.customClass = function(date) {
                    return $scope.customClass({
                        date: date,
                        mode: $scope.datepickerMode
                    });
                };
                this.split = function(arr, size) {
                    var arrays = [];
                    while (arr.length > 0) {
                        arrays.push(arr.splice(0, size));
                    }
                    return arrays;
                };
                $scope.select = function(date) {
                    if ($scope.datepickerMode === self.minMode) {
                        var dt = ngModelCtrl.$viewValue ? dateParser.fromTimezone(new Date(ngModelCtrl.$viewValue), ngModelOptions.timezone) : new Date(0, 0, 0, 0, 0, 0, 0);
                        dt.setFullYear(date.getFullYear(), date.getMonth(), date.getDate());
                        dt = dateParser.toTimezone(dt, ngModelOptions.timezone);
                        ngModelCtrl.$setViewValue(dt);
                        ngModelCtrl.$render();
                    } else {
                        self.activeDate = date;
                        $scope.datepickerMode = self.modes[self.modes.indexOf($scope.datepickerMode) - 1];
                    }
                };
                $scope.move = function(direction) {
                    var year = self.activeDate.getFullYear() + direction * (self.step.years || 0),
                        month = self.activeDate.getMonth() + direction * (self.step.months || 0);
                    self.activeDate.setFullYear(year, month, 1);
                    self.refreshView();
                };
                $scope.toggleMode = function(direction) {
                    direction = direction || 1;
                    if ($scope.datepickerMode === self.maxMode && direction === 1 ||
                        $scope.datepickerMode === self.minMode && direction === -1) {
                        return;
                    }
                    $scope.datepickerMode = self.modes[self.modes.indexOf($scope.datepickerMode) + direction];
                };
                $scope.keys = {
                    13: 'enter',
                    32: 'space',
                    33: 'pageup',
                    34: 'pagedown',
                    35: 'end',
                    36: 'home',
                    37: 'left',
                    38: 'up',
                    39: 'right',
                    40: 'down'
                };
                var focusElement = function() {
                    self.element[0].focus();
                };
                $scope.$on('uib:datepicker.focus', focusElement);
                $scope.keydown = function(evt) {
                    var key = $scope.keys[evt.which];
                    if (!key || evt.shiftKey || evt.altKey || $scope.disabled) {
                        return;
                    }
                    evt.preventDefault();
                    if (!self.shortcutPropagation) {
                        evt.stopPropagation();
                    }
                    if (key === 'enter' || key === 'space') {
                        if (self.isDisabled(self.activeDate)) {
                            return;
                        }
                        $scope.select(self.activeDate);
                    } else if (evt.ctrlKey && (key === 'up' || key === 'down')) {
                        $scope.toggleMode(key === 'up' ? 1 : -1);
                    } else {
                        self.handleKeyDown(key, evt);
                        self.refreshView();
                    }
                };
                $scope.$on("$destroy", function() {
                    while (watchListeners.length) {
                        watchListeners.shift()();
                    }
                });
            }
        ])
        .controller('UibDaypickerController', ['$scope', '$element', 'dateFilter', function(scope, $element, dateFilter) {
            var DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
            this.step = {
                months: 1
            };
            this.element = $element;
    
            function getDaysInMonth(year, month) {
                return month === 1 && year % 4 === 0 &&
                    (year % 100 !== 0 || year % 400 === 0) ? 29 : DAYS_IN_MONTH[month];
            }
            this.init = function(ctrl) {
                angular.extend(ctrl, this);
                scope.showWeeks = ctrl.showWeeks;
                ctrl.refreshView();
            };
            this.getDates = function(startDate, n) {
                var dates = new Array(n),
                    current = new Date(startDate),
                    i = 0,
                    date;
                while (i < n) {
                    date = new Date(current);
                    dates[i++] = date;
                    current.setDate(current.getDate() + 1);
                }
                return dates;
            };
            this._refreshView = function() {
                var year = this.activeDate.getFullYear(),
                    month = this.activeDate.getMonth(),
                    firstDayOfMonth = new Date(this.activeDate);
                firstDayOfMonth.setFullYear(year, month, 1);
                var difference = this.startingDay - firstDayOfMonth.getDay(),
                    numDisplayedFromPreviousMonth = difference > 0 ?
                    7 - difference : -difference,
                    firstDate = new Date(firstDayOfMonth);
                if (numDisplayedFromPreviousMonth > 0) {
                    firstDate.setDate(-numDisplayedFromPreviousMonth + 1);
                }
                var days = this.getDates(firstDate, 42);
                for (var i = 0; i < 42; i++) {
                    days[i] = angular.extend(this.createDateObject(days[i], this.formatDay), {
                        secondary: days[i].getMonth() !== month,
                        uid: scope.uniqueId + '-' + i
                    });
                }
                scope.labels = new Array(7);
                for (var j = 0; j < 7; j++) {
                    scope.labels[j] = {
                        abbr: dateFilter(days[j].date, this.formatDayHeader),
                        full: dateFilter(days[j].date, 'EEEE')
                    };
                }
                scope.title = dateFilter(this.activeDate, this.formatDayTitle);
                scope.rows = this.split(days, 7);
                if (scope.showWeeks) {
                    scope.weekNumbers = [];
                    var thursdayIndex = (4 + 7 - this.startingDay) % 7,
                        numWeeks = scope.rows.length;
                    for (var curWeek = 0; curWeek < numWeeks; curWeek++) {
                        scope.weekNumbers.push(
                            getISO8601WeekNumber(scope.rows[curWeek][thursdayIndex].date));
                    }
                }
            };
            this.compare = function(date1, date2) {
                var _date1 = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate());
                var _date2 = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate());
                _date1.setFullYear(date1.getFullYear());
                _date2.setFullYear(date2.getFullYear());
                return _date1 - _date2;
            };
    
            function getISO8601WeekNumber(date) {
                var checkDate = new Date(date);
                checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
                var time = checkDate.getTime();
                checkDate.setMonth(0);
                checkDate.setDate(1);
                return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
            }
            this.handleKeyDown = function(key, evt) {
                var date = this.activeDate.getDate();
                if (key === 'left') {
                    date = date - 1;
                } else if (key === 'up') {
                    date = date - 7;
                } else if (key === 'right') {
                    date = date + 1;
                } else if (key === 'down') {
                    date = date + 7;
                } else if (key === 'pageup' || key === 'pagedown') {
                    var month = this.activeDate.getMonth() + (key === 'pageup' ? -1 : 1);
                    this.activeDate.setMonth(month, 1);
                    date = Math.min(getDaysInMonth(this.activeDate.getFullYear(), this.activeDate.getMonth()), date);
                } else if (key === 'home') {
                    date = 1;
                } else if (key === 'end') {
                    date = getDaysInMonth(this.activeDate.getFullYear(), this.activeDate.getMonth());
                }
                this.activeDate.setDate(date);
            };
        }])
        .controller('UibMonthpickerController', ['$scope', '$element', 'dateFilter', function(scope, $element, dateFilter) {
            this.step = {
                years: 1
            };
            this.element = $element;
            this.init = function(ctrl) {
                angular.extend(ctrl, this);
                ctrl.refreshView();
            };
            this._refreshView = function() {
                var months = new Array(12),
                    year = this.activeDate.getFullYear(),
                    date;
                for (var i = 0; i < 12; i++) {
                    date = new Date(this.activeDate);
                    date.setFullYear(year, i, 1);
                    months[i] = angular.extend(this.createDateObject(date, this.formatMonth), {
                        uid: scope.uniqueId + '-' + i
                    });
                }
                scope.title = dateFilter(this.activeDate, this.formatMonthTitle);
                scope.rows = this.split(months, 3);
            };
            this.compare = function(date1, date2) {
                var _date1 = new Date(date1.getFullYear(), date1.getMonth());
                var _date2 = new Date(date2.getFullYear(), date2.getMonth());
                _date1.setFullYear(date1.getFullYear());
                _date2.setFullYear(date2.getFullYear());
                return _date1 - _date2;
            };
            this.handleKeyDown = function(key, evt) {
                var date = this.activeDate.getMonth();
                if (key === 'left') {
                    date = date - 1;
                } else if (key === 'up') {
                    date = date - 3;
                } else if (key === 'right') {
                    date = date + 1;
                } else if (key === 'down') {
                    date = date + 3;
                } else if (key === 'pageup' || key === 'pagedown') {
                    var year = this.activeDate.getFullYear() + (key === 'pageup' ? -1 : 1);
                    this.activeDate.setFullYear(year);
                } else if (key === 'home') {
                    date = 0;
                } else if (key === 'end') {
                    date = 11;
                }
                this.activeDate.setMonth(date);
            };
        }])
        .controller('UibYearpickerController', ['$scope', '$element', 'dateFilter', function(scope, $element, dateFilter) {
            var columns, range;
            this.element = $element;
    
            function getStartingYear(year) {
                return parseInt((year - 1) / range, 10) * range + 1;
            }
            this.yearpickerInit = function() {
                columns = this.yearColumns;
                range = this.yearRows * columns;
                this.step = {
                    years: range
                };
            };
            this._refreshView = function() {
                var years = new Array(range),
                    date;
                for (var i = 0, start = getStartingYear(this.activeDate.getFullYear()); i < range; i++) {
                    date = new Date(this.activeDate);
                    date.setFullYear(start + i, 0, 1);
                    years[i] = angular.extend(this.createDateObject(date, this.formatYear), {
                        uid: scope.uniqueId + '-' + i
                    });
                }
                scope.title = [years[0].label, years[range - 1].label].join(' - ');
                scope.rows = this.split(years, columns);
                scope.columns = columns;
            };
            this.compare = function(date1, date2) {
                return date1.getFullYear() - date2.getFullYear();
            };
            this.handleKeyDown = function(key, evt) {
                var date = this.activeDate.getFullYear();
                if (key === 'left') {
                    date = date - 1;
                } else if (key === 'up') {
                    date = date - columns;
                } else if (key === 'right') {
                    date = date + 1;
                } else if (key === 'down') {
                    date = date + columns;
                } else if (key === 'pageup' || key === 'pagedown') {
                    date += (key === 'pageup' ? -1 : 1) * range;
                } else if (key === 'home') {
                    date = getStartingYear(this.activeDate.getFullYear());
                } else if (key === 'end') {
                    date = getStartingYear(this.activeDate.getFullYear()) + range - 1;
                }
                this.activeDate.setFullYear(date);
            };
        }])
        .directive('uibDatepicker', function() {
            return {
                replace: true,
                templateUrl: function(element, attrs) {
                    return attrs.templateUrl || 'uib/template/datepicker/datepicker.html';
                },
                scope: {
                    datepickerMode: '=?',
                    datepickerOptions: '=?',
                    dateDisabled: '&',
                    customClass: '&',
                    shortcutPropagation: '&?'
                },
                require: ['uibDatepicker', '^ngModel'],
                controller: 'UibDatepickerController',
                controllerAs: 'datepicker',
                link: function(scope, element, attrs, ctrls) {
                    var datepickerCtrl = ctrls[0],
                        ngModelCtrl = ctrls[1];
                    datepickerCtrl.init(ngModelCtrl);
                }
            };
        })
        .directive('uibDaypicker', function() {
            return {
                replace: true,
                templateUrl: function(element, attrs) {
                    return attrs.templateUrl || 'uib/template/datepicker/day.html';
                },
                require: ['^uibDatepicker', 'uibDaypicker'],
                controller: 'UibDaypickerController',
                link: function(scope, element, attrs, ctrls) {
                    var datepickerCtrl = ctrls[0],
                        daypickerCtrl = ctrls[1];
                    daypickerCtrl.init(datepickerCtrl);
                }
            };
        })
        .directive('uibMonthpicker', function() {
            return {
                replace: true,
                templateUrl: function(element, attrs) {
                    return attrs.templateUrl || 'uib/template/datepicker/month.html';
                },
                require: ['^uibDatepicker', 'uibMonthpicker'],
                controller: 'UibMonthpickerController',
                link: function(scope, element, attrs, ctrls) {
                    var datepickerCtrl = ctrls[0],
                        monthpickerCtrl = ctrls[1];
                    monthpickerCtrl.init(datepickerCtrl);
                }
            };
        })
        .directive('uibYearpicker', function() {
            return {
                replace: true,
                templateUrl: function(element, attrs) {
                    return attrs.templateUrl || 'uib/template/datepicker/year.html';
                },
                require: ['^uibDatepicker', 'uibYearpicker'],
                controller: 'UibYearpickerController',
                link: function(scope, element, attrs, ctrls) {
                    var ctrl = ctrls[0];
                    angular.extend(ctrl, ctrls[1]);
                    ctrl.yearpickerInit();
                    ctrl.refreshView();
                }
            };
        })
        .constant('uibDatepickerPopupConfig', {
            altInputFormats: [],
            appendToBody: false,
            clearText: 'Clear',
            closeOnDateSelection: true,
            closeText: 'Done',
            currentText: 'Today',
            datepickerPopup: 'yyyy-MM-dd',
            datepickerPopupTemplateUrl: 'uib/template/datepicker/popup.html',
            datepickerTemplateUrl: 'uib/template/datepicker/datepicker.html',
            html5Types: {
                date: 'yyyy-MM-dd',
                'datetime-local': 'yyyy-MM-ddTHH:mm:ss.sss',
                'month': 'yyyy-MM'
            },
            onOpenFocus: true,
            showButtonBar: true
        })
        .controller('UibDatepickerPopupController', ['$scope', '$element', '$attrs', '$compile', '$parse', '$document', '$rootScope', '$uibPosition', 'dateFilter', 'uibDateParser', 'uibDatepickerPopupConfig', '$timeout', 'uibDatepickerConfig',
            function(scope, element, attrs, $compile, $parse, $document, $rootScope, $position, dateFilter, dateParser, datepickerPopupConfig, $timeout, datepickerConfig) {
                var cache = {},
                    isHtml5DateInput = false;
                var dateFormat, closeOnDateSelection, appendToBody, onOpenFocus,
                    datepickerPopupTemplateUrl, datepickerTemplateUrl, popupEl, datepickerEl,
                    ngModel, ngModelOptions, $popup, altInputFormats, watchListeners = [];
                scope.watchData = {};
                this.init = function(_ngModel_) {
                    ngModel = _ngModel_;
                    ngModelOptions = _ngModel_.$options || datepickerConfig.ngModelOptions;
                    closeOnDateSelection = angular.isDefined(attrs.closeOnDateSelection) ? scope.$parent.$eval(attrs.closeOnDateSelection) : datepickerPopupConfig.closeOnDateSelection;
                    appendToBody = angular.isDefined(attrs.datepickerAppendToBody) ? scope.$parent.$eval(attrs.datepickerAppendToBody) : datepickerPopupConfig.appendToBody;
                    onOpenFocus = angular.isDefined(attrs.onOpenFocus) ? scope.$parent.$eval(attrs.onOpenFocus) : datepickerPopupConfig.onOpenFocus;
                    datepickerPopupTemplateUrl = angular.isDefined(attrs.datepickerPopupTemplateUrl) ? attrs.datepickerPopupTemplateUrl : datepickerPopupConfig.datepickerPopupTemplateUrl;
                    datepickerTemplateUrl = angular.isDefined(attrs.datepickerTemplateUrl) ? attrs.datepickerTemplateUrl : datepickerPopupConfig.datepickerTemplateUrl;
                    altInputFormats = angular.isDefined(attrs.altInputFormats) ? scope.$parent.$eval(attrs.altInputFormats) : datepickerPopupConfig.altInputFormats;
                    scope.showButtonBar = angular.isDefined(attrs.showButtonBar) ? scope.$parent.$eval(attrs.showButtonBar) : datepickerPopupConfig.showButtonBar;
                    if (datepickerPopupConfig.html5Types[attrs.type]) {
                        dateFormat = datepickerPopupConfig.html5Types[attrs.type];
                        isHtml5DateInput = true;
                    } else {
                        dateFormat = attrs.uibDatepickerPopup || datepickerPopupConfig.datepickerPopup;
                        attrs.$observe('uibDatepickerPopup', function(value, oldValue) {
                            var newDateFormat = value || datepickerPopupConfig.datepickerPopup;
                            if (newDateFormat !== dateFormat) {
                                dateFormat = newDateFormat;
                                ngModel.$modelValue = null;
                                if (!dateFormat) {
                                    throw new Error('uibDatepickerPopup must have a date format specified.');
                                }
                            }
                        });
                    }
                    if (!dateFormat) {
                        throw new Error('uibDatepickerPopup must have a date format specified.');
                    }
                    if (isHtml5DateInput && attrs.uibDatepickerPopup) {
                        throw new Error('HTML5 date input types do not support custom formats.');
                    }
                    popupEl = angular.element('<div uib-datepicker-popup-wrap><div uib-datepicker></div></div>');
                    scope.ngModelOptions = angular.copy(ngModelOptions);
                    scope.ngModelOptions.timezone = null;
                    popupEl.attr({
                        'ng-model': 'date',
                        'ng-model-options': 'ngModelOptions',
                        'ng-change': 'dateSelection(date)',
                        'template-url': datepickerPopupTemplateUrl
                    });
                    datepickerEl = angular.element(popupEl.children()[0]);
                    datepickerEl.attr('template-url', datepickerTemplateUrl);
                    if (isHtml5DateInput) {
                        if (attrs.type === 'month') {
                            datepickerEl.attr('datepicker-mode', '"month"');
                            datepickerEl.attr('min-mode', 'month');
                        }
                    }
                    if (scope.datepickerOptions) {
                        angular.forEach(scope.datepickerOptions, function(value, option) {
                            if (['minDate', 'maxDate', 'minMode', 'maxMode', 'initDate', 'datepickerMode'].indexOf(option) === -1) {
                                datepickerEl.attr(cameltoDash(option), value);
                            } else {
                                datepickerEl.attr(cameltoDash(option), 'datepickerOptions.' + option);
                            }
                        });
                    }
                    angular.forEach(['minMode', 'maxMode', 'datepickerMode', 'shortcutPropagation'], function(key) {
                        if (attrs[key]) {
                            var getAttribute = $parse(attrs[key]);
                            var propConfig = {
                                get: function() {
                                    return getAttribute(scope.$parent);
                                }
                            };
                            datepickerEl.attr(cameltoDash(key), 'watchData.' + key);
                            if (key === 'datepickerMode') {
                                var setAttribute = getAttribute.assign;
                                propConfig.set = function(v) {
                                    setAttribute(scope.$parent, v);
                                };
                            }
                            Object.defineProperty(scope.watchData, key, propConfig);
                        }
                    });
                    angular.forEach(['minDate', 'maxDate', 'initDate'], function(key) {
                        if (attrs[key]) {
                            var getAttribute = $parse(attrs[key]);
                            watchListeners.push(scope.$parent.$watch(getAttribute, function(value) {
                                if (key === 'minDate' || key === 'maxDate') {
                                    if (value === null) {
                                        cache[key] = null;
                                    } else if (angular.isDate(value)) {
                                        cache[key] = dateParser.fromTimezone(new Date(value), ngModelOptions.timezone);
                                    } else {
                                        cache[key] = new Date(dateFilter(value, 'medium'));
                                    }
                                    scope.watchData[key] = value === null ? null : cache[key];
                                } else {
                                    scope.watchData[key] = dateParser.fromTimezone(new Date(value), ngModelOptions.timezone);
                                }
                            }));
                            datepickerEl.attr(cameltoDash(key), 'watchData.' + key);
                        }
                    });
                    if (attrs.dateDisabled) {
                        datepickerEl.attr('date-disabled', 'dateDisabled({ date: date, mode: mode })');
                    }
                    angular.forEach(['formatDay', 'formatMonth', 'formatYear', 'formatDayHeader', 'formatDayTitle', 'formatMonthTitle', 'showWeeks', 'startingDay', 'yearRows', 'yearColumns'], function(key) {
                        if (angular.isDefined(attrs[key])) {
                            datepickerEl.attr(cameltoDash(key), attrs[key]);
                        }
                    });
                    if (attrs.customClass) {
                        datepickerEl.attr('custom-class', 'customClass({ date: date, mode: mode })');
                    }
                    if (!isHtml5DateInput) {
                        ngModel.$$parserName = 'date';
                        ngModel.$validators.date = validator;
                        ngModel.$parsers.unshift(parseDate);
                        ngModel.$formatters.push(function(value) {
                            if (ngModel.$isEmpty(value)) {
                                scope.date = value;
                                return value;
                            }
                            scope.date = dateParser.fromTimezone(value, ngModelOptions.timezone);
                            if (angular.isNumber(scope.date)) {
                                scope.date = new Date(scope.date);
                            }
                            return dateParser.filter(scope.date, dateFormat);
                        });
                    } else {
                        ngModel.$formatters.push(function(value) {
                            scope.date = dateParser.fromTimezone(value, ngModelOptions.timezone);
                            return value;
                        });
                    }
                    ngModel.$viewChangeListeners.push(function() {
                        scope.date = parseDateString(ngModel.$viewValue);
                    });
                    element.on('keydown', inputKeydownBind);
                    $popup = $compile(popupEl)(scope);
                    popupEl.remove();
                    if (appendToBody) {
                        $document.find('body').append($popup);
                    } else {
                        element.after($popup);
                    }
                    scope.$on('$destroy', function() {
                        if (scope.isOpen === true) {
                            if (!$rootScope.$$phase) {
                                scope.$apply(function() {
                                    scope.isOpen = false;
                                });
                            }
                        }
                        $popup.remove();
                        element.off('keydown', inputKeydownBind);
                        $document.off('click', documentClickBind);
                        while (watchListeners.length) {
                            watchListeners.shift()();
                        }
                    });
                };
                scope.getText = function(key) {
                    return scope[key + 'Text'] || datepickerPopupConfig[key + 'Text'];
                };
                scope.isDisabled = function(date) {
                    if (date === 'today') {
                        date = new Date();
                    }
                    return scope.watchData.minDate && scope.compare(date, cache.minDate) < 0 ||
                        scope.watchData.maxDate && scope.compare(date, cache.maxDate) > 0;
                };
                scope.compare = function(date1, date2) {
                    return new Date(date1.getFullYear(), date1.getMonth(), date1.getDate()) - new Date(date2.getFullYear(), date2.getMonth(), date2.getDate());
                };
                scope.dateSelection = function(dt) {
                    if (angular.isDefined(dt)) {
                        scope.date = dt;
                    }
                    var date = scope.date ? dateParser.filter(scope.date, dateFormat) : null;
                    element.val(date);
                    ngModel.$setViewValue(date);
                    if (closeOnDateSelection) {
                        scope.isOpen = false;
                        element[0].focus();
                    }
                };
                scope.keydown = function(evt) {
                    if (evt.which === 27) {
                        evt.stopPropagation();
                        scope.isOpen = false;
                        element[0].focus();
                    }
                };
                scope.select = function(date) {
                    if (date === 'today') {
                        var today = new Date();
                        if (angular.isDate(scope.date)) {
                            date = new Date(scope.date);
                            date.setFullYear(today.getFullYear(), today.getMonth(), today.getDate());
                        } else {
                            date = new Date(today.setHours(0, 0, 0, 0));
                        }
                    }
                    scope.dateSelection(date);
                };
                scope.close = function() {
                    scope.isOpen = false;
                    element[0].focus();
                };
                scope.disabled = angular.isDefined(attrs.disabled) || false;
                if (attrs.ngDisabled) {
                    watchListeners.push(scope.$parent.$watch($parse(attrs.ngDisabled), function(disabled) {
                        scope.disabled = disabled;
                    }));
                }
                scope.$watch('isOpen', function(value) {
                    if (value) {
                        if (!scope.disabled) {
                            scope.position = appendToBody ? $position.offset(element) : $position.position(element);
                            scope.position.top = scope.position.top + element.prop('offsetHeight');
                            $timeout(function() {
                                if (onOpenFocus) {
                                    scope.$broadcast('uib:datepicker.focus');
                                }
                                $document.on('click', documentClickBind);
                            }, 0, false);
                        } else {
                            scope.isOpen = false;
                        }
                    } else {
                        $document.off('click', documentClickBind);
                    }
                });
    
                function cameltoDash(string) {
                    return string.replace(/([A-Z])/g, function($1) {
                        return '-' + $1.toLowerCase();
                    });
                }
    
                function parseDateString(viewValue) {
                    var date = dateParser.parse(viewValue, dateFormat, scope.date);
                    if (isNaN(date)) {
                        for (var i = 0; i < altInputFormats.length; i++) {
                            date = dateParser.parse(viewValue, altInputFormats[i], scope.date);
                            if (!isNaN(date)) {
                                return date;
                            }
                        }
                    }
                    return date;
                }
    
                function parseDate(viewValue) {
                    if (angular.isNumber(viewValue)) {
                        viewValue = new Date(viewValue);
                    }
                    if (!viewValue) {
                        return null;
                    }
                    if (angular.isDate(viewValue) && !isNaN(viewValue)) {
                        return viewValue;
                    }
                    if (angular.isString(viewValue)) {
                        var date = parseDateString(viewValue);
                        if (!isNaN(date)) {
                            return dateParser.toTimezone(date, ngModelOptions.timezone);
                        }
                    }
                    return ngModel.$options && ngModel.$options.allowInvalid ? viewValue : undefined;
                }
    
                function validator(modelValue, viewValue) {
                    var value = modelValue || viewValue;
                    if (!attrs.ngRequired && !value) {
                        return true;
                    }
                    if (angular.isNumber(value)) {
                        value = new Date(value);
                    }
                    if (!value) {
                        return true;
                    }
                    if (angular.isDate(value) && !isNaN(value)) {
                        return true;
                    }
                    if (angular.isString(value)) {
                        return !isNaN(parseDateString(viewValue));
                    }
                    return false;
                }
    
                function documentClickBind(event) {
                    if (!scope.isOpen && scope.disabled) {
                        return;
                    }
                    var popup = $popup[0];
                    var dpContainsTarget = element[0].contains(event.target);
                    var popupContainsTarget = popup.contains !== undefined && popup.contains(event.target);
                    if (scope.isOpen && !(dpContainsTarget || popupContainsTarget)) {
                        scope.$apply(function() {
                            scope.isOpen = false;
                        });
                    }
                }
    
                function inputKeydownBind(evt) {
                    if (evt.which === 27 && scope.isOpen) {
                        evt.preventDefault();
                        evt.stopPropagation();
                        scope.$apply(function() {
                            scope.isOpen = false;
                        });
                        element[0].focus();
                    } else if (evt.which === 40 && !scope.isOpen) {
                        evt.preventDefault();
                        evt.stopPropagation();
                        scope.$apply(function() {
                            scope.isOpen = true;
                        });
                    }
                }
            }
        ])
        .directive('uibDatepickerPopup', function() {
            return {
                require: ['ngModel', 'uibDatepickerPopup'],
                controller: 'UibDatepickerPopupController',
                scope: {
                    datepickerOptions: '=?',
                    isOpen: '=?',
                    currentText: '@',
                    clearText: '@',
                    closeText: '@',
                    dateDisabled: '&',
                    customClass: '&'
                },
                link: function(scope, element, attrs, ctrls) {
                    var ngModel = ctrls[0],
                        ctrl = ctrls[1];
                    ctrl.init(ngModel);
                }
            };
        })
        .directive('uibDatepickerPopupWrap', function() {
            return {
                replace: true,
                transclude: true,
                templateUrl: function(element, attrs) {
                    return attrs.templateUrl || 'uib/template/datepicker/popup.html';
                }
            };
        });
    angular.module('ui.bootstrap.debounce', [])
        .factory('$$debounce', ['$timeout', function($timeout) {
            return function(callback, debounceTime) {
                var timeoutPromise;
                return function() {
                    var self = this;
                    var args = Array.prototype.slice.call(arguments);
                    if (timeoutPromise) {
                        $timeout.cancel(timeoutPromise);
                    }
                    timeoutPromise = $timeout(function() {
                        callback.apply(self, args);
                    }, debounceTime);
                };
            };
        }]);
    angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position'])
        .constant('uibDropdownConfig', {
            appendToOpenClass: 'uib-dropdown-open',
            openClass: 'open'
        })
        .service('uibDropdownService', ['$document', '$rootScope', function($document, $rootScope) {
            var openScope = null;
            this.open = function(dropdownScope) {
                if (!openScope) {
                    $document.on('click', closeDropdown);
                    $document.on('keydown', keybindFilter);
                }
                if (openScope && openScope !== dropdownScope) {
                    openScope.isOpen = false;
                }
                openScope = dropdownScope;
            };
            this.close = function(dropdownScope) {
                if (openScope === dropdownScope) {
                    openScope = null;
                    $document.off('click', closeDropdown);
                    $document.off('keydown', keybindFilter);
                }
            };
            var closeDropdown = function(evt) {
                if (!openScope) {
                    return;
                }
                if (evt && openScope.getAutoClose() === 'disabled') {
                    return;
                }
                if (evt && evt.which === 3) {
                    return;
                }
                var toggleElement = openScope.getToggleElement();
                if (evt && toggleElement && toggleElement[0].contains(evt.target)) {
                    return;
                }
                var dropdownElement = openScope.getDropdownElement();
                if (evt && openScope.getAutoClose() === 'outsideClick' &&
                    dropdownElement && dropdownElement[0].contains(evt.target)) {
                    return;
                }
                openScope.isOpen = false;
                if (!$rootScope.$$phase) {
                    openScope.$apply();
                }
            };
            var keybindFilter = function(evt) {
                if (evt.which === 27) {
                    openScope.focusToggleElement();
                    closeDropdown();
                } else if (openScope.isKeynavEnabled() && [38, 40].indexOf(evt.which) !== -1 && openScope.isOpen) {
                    evt.preventDefault();
                    evt.stopPropagation();
                    openScope.focusDropdownEntry(evt.which);
                }
            };
        }])
        .controller('UibDropdownController', ['$scope', '$element', '$attrs', '$parse', 'uibDropdownConfig', 'uibDropdownService', '$animate', '$uibPosition', '$document', '$compile', '$templateRequest', function($scope, $element, $attrs, $parse, dropdownConfig, uibDropdownService, $animate, $position, $document, $compile, $templateRequest) {
            var self = this,
                scope = $scope.$new(),
                templateScope,
                appendToOpenClass = dropdownConfig.appendToOpenClass,
                openClass = dropdownConfig.openClass,
                getIsOpen,
                setIsOpen = angular.noop,
                toggleInvoker = $attrs.onToggle ? $parse($attrs.onToggle) : angular.noop,
                appendToBody = false,
                appendTo = null,
                keynavEnabled = false,
                selectedOption = null,
                body = $document.find('body');
            $element.addClass('dropdown');
            this.init = function() {
                if ($attrs.isOpen) {
                    getIsOpen = $parse($attrs.isOpen);
                    setIsOpen = getIsOpen.assign;
                    $scope.$watch(getIsOpen, function(value) {
                        scope.isOpen = !!value;
                    });
                }
                if (angular.isDefined($attrs.dropdownAppendTo)) {
                    var appendToEl = $parse($attrs.dropdownAppendTo)(scope);
                    if (appendToEl) {
                        appendTo = angular.element(appendToEl);
                    }
                }
                appendToBody = angular.isDefined($attrs.dropdownAppendToBody);
                keynavEnabled = angular.isDefined($attrs.keyboardNav);
                if (appendToBody && !appendTo) {
                    appendTo = body;
                }
                if (appendTo && self.dropdownMenu) {
                    appendTo.append(self.dropdownMenu);
                    $element.on('$destroy', function handleDestroyEvent() {
                        self.dropdownMenu.remove();
                    });
                }
            };
            this.toggle = function(open) {
                return scope.isOpen = arguments.length ? !!open : !scope.isOpen;
            };
            this.isOpen = function() {
                return scope.isOpen;
            };
            scope.getToggleElement = function() {
                return self.toggleElement;
            };
            scope.getAutoClose = function() {
                return $attrs.autoClose || 'always';
            };
            scope.getElement = function() {
                return $element;
            };
            scope.isKeynavEnabled = function() {
                return keynavEnabled;
            };
            scope.focusDropdownEntry = function(keyCode) {
                var elems = self.dropdownMenu ?
                    angular.element(self.dropdownMenu).find('a') :
                    $element.find('ul').eq(0).find('a');
                switch (keyCode) {
                    case 40:
                        {
                            if (!angular.isNumber(self.selectedOption)) {
                                self.selectedOption = 0;
                            } else {
                                self.selectedOption = self.selectedOption === elems.length - 1 ?
                                    self.selectedOption :
                                    self.selectedOption + 1;
                            }
                            break;
                        }
                    case 38:
                        {
                            if (!angular.isNumber(self.selectedOption)) {
                                self.selectedOption = elems.length - 1;
                            } else {
                                self.selectedOption = self.selectedOption === 0 ?
                                    0 : self.selectedOption - 1;
                            }
                            break;
                        }
                }
                elems[self.selectedOption].focus();
            };
            scope.getDropdownElement = function() {
                return self.dropdownMenu;
            };
            scope.focusToggleElement = function() {
                if (self.toggleElement) {
                    self.toggleElement[0].focus();
                }
            };
            scope.$watch('isOpen', function(isOpen, wasOpen) {
                if (appendTo && self.dropdownMenu) {
                    var pos = $position.positionElements($element, self.dropdownMenu, 'bottom-left', true),
                        css,
                        rightalign;
                    css = {
                        top: pos.top + 'px',
                        display: isOpen ? 'block' : 'none'
                    };
                    rightalign = self.dropdownMenu.hasClass('dropdown-menu-right');
                    if (!rightalign) {
                        css.left = pos.left + 'px';
                        css.right = 'auto';
                    } else {
                        css.left = 'auto';
                        css.right = window.innerWidth -
                            (pos.left + $element.prop('offsetWidth')) + 'px';
                    }
                    if (!appendToBody) {
                        var appendOffset = $position.offset(appendTo);
                        css.top = pos.top - appendOffset.top + 'px';
                        if (!rightalign) {
                            css.left = pos.left - appendOffset.left + 'px';
                        } else {
                            css.right = window.innerWidth -
                                (pos.left - appendOffset.left + $element.prop('offsetWidth')) + 'px';
                        }
                    }
                    self.dropdownMenu.css(css);
                }
                var openContainer = appendTo ? appendTo : $element;
                $animate[isOpen ? 'addClass' : 'removeClass'](openContainer, appendTo ? appendToOpenClass : openClass).then(function() {
                    if (angular.isDefined(isOpen) && isOpen !== wasOpen) {
                        toggleInvoker($scope, {
                            open: !!isOpen
                        });
                    }
                });
                if (isOpen) {
                    if (self.dropdownMenuTemplateUrl) {
                        $templateRequest(self.dropdownMenuTemplateUrl).then(function(tplContent) {
                            templateScope = scope.$new();
                            $compile(tplContent.trim())(templateScope, function(dropdownElement) {
                                var newEl = dropdownElement;
                                self.dropdownMenu.replaceWith(newEl);
                                self.dropdownMenu = newEl;
                            });
                        });
                    }
                    scope.focusToggleElement();
                    uibDropdownService.open(scope);
                } else {
                    if (self.dropdownMenuTemplateUrl) {
                        if (templateScope) {
                            templateScope.$destroy();
                        }
                        var newEl = angular.element('<ul class="dropdown-menu"></ul>');
                        self.dropdownMenu.replaceWith(newEl);
                        self.dropdownMenu = newEl;
                    }
                    uibDropdownService.close(scope);
                    self.selectedOption = null;
                }
                if (angular.isFunction(setIsOpen)) {
                    setIsOpen($scope, isOpen);
                }
            });
            $scope.$on('$locationChangeSuccess', function() {
                if (scope.getAutoClose() !== 'disabled') {
                    scope.isOpen = false;
                }
            });
        }])
        .directive('uibDropdown', function() {
            return {
                controller: 'UibDropdownController',
                link: function(scope, element, attrs, dropdownCtrl) {
                    dropdownCtrl.init();
                }
            };
        })
        .directive('uibDropdownMenu', function() {
            return {
                restrict: 'A',
                require: '?^uibDropdown',
                link: function(scope, element, attrs, dropdownCtrl) {
                    if (!dropdownCtrl || angular.isDefined(attrs.dropdownNested)) {
                        return;
                    }
                    element.addClass('dropdown-menu');
                    var tplUrl = attrs.templateUrl;
                    if (tplUrl) {
                        dropdownCtrl.dropdownMenuTemplateUrl = tplUrl;
                    }
                    if (!dropdownCtrl.dropdownMenu) {
                        dropdownCtrl.dropdownMenu = element;
                    }
                }
            };
        })
        .directive('uibDropdownToggle', function() {
            return {
                require: '?^uibDropdown',
                link: function(scope, element, attrs, dropdownCtrl) {
                    if (!dropdownCtrl) {
                        return;
                    }
                    element.addClass('dropdown-toggle');
                    dropdownCtrl.toggleElement = element;
                    var toggleDropdown = function(event) {
                        event.preventDefault();
                        if (!element.hasClass('disabled') && !attrs.disabled) {
                            scope.$apply(function() {
                                dropdownCtrl.toggle();
                            });
                        }
                    };
                    element.bind('click', toggleDropdown);
                    element.attr({
                        'aria-haspopup': true,
                        'aria-expanded': false
                    });
                    scope.$watch(dropdownCtrl.isOpen, function(isOpen) {
                        element.attr('aria-expanded', !!isOpen);
                    });
                    scope.$on('$destroy', function() {
                        element.unbind('click', toggleDropdown);
                    });
                }
            };
        });
    angular.module('ui.bootstrap.stackedMap', [])
        .factory('$$stackedMap', function() {
            return {
                createNew: function() {
                    var stack = [];
                    return {
                        add: function(key, value) {
                            stack.push({
                                key: key,
                                value: value
                            });
                        },
                        get: function(key) {
                            for (var i = 0; i < stack.length; i++) {
                                if (key === stack[i].key) {
                                    return stack[i];
                                }
                            }
                        },
                        keys: function() {
                            var keys = [];
                            for (var i = 0; i < stack.length; i++) {
                                keys.push(stack[i].key);
                            }
                            return keys;
                        },
                        top: function() {
                            return stack[stack.length - 1];
                        },
                        remove: function(key) {
                            var idx = -1;
                            for (var i = 0; i < stack.length; i++) {
                                if (key === stack[i].key) {
                                    idx = i;
                                    break;
                                }
                            }
                            return stack.splice(idx, 1)[0];
                        },
                        removeTop: function() {
                            return stack.splice(stack.length - 1, 1)[0];
                        },
                        length: function() {
                            return stack.length;
                        }
                    };
                }
            };
        });
    angular.module('ui.bootstrap.modal', ['ui.bootstrap.stackedMap'])
        .factory('$$multiMap', function() {
            return {
                createNew: function() {
                    var map = {};
                    return {
                        entries: function() {
                            return Object.keys(map).map(function(key) {
                                return {
                                    key: key,
                                    value: map[key]
                                };
                            });
                        },
                        get: function(key) {
                            return map[key];
                        },
                        hasKey: function(key) {
                            return !!map[key];
                        },
                        keys: function() {
                            return Object.keys(map);
                        },
                        put: function(key, value) {
                            if (!map[key]) {
                                map[key] = [];
                            }
                            map[key].push(value);
                        },
                        remove: function(key, value) {
                            var values = map[key];
                            if (!values) {
                                return;
                            }
                            var idx = values.indexOf(value);
                            if (idx !== -1) {
                                values.splice(idx, 1);
                            }
                            if (!values.length) {
                                delete map[key];
                            }
                        }
                    };
                }
            };
        })
        .provider('$uibResolve', function() {
            var resolve = this;
            this.resolver = null;
            this.setResolver = function(resolver) {
                this.resolver = resolver;
            };
            this.$get = ['$injector', '$q', function($injector, $q) {
                var resolver = resolve.resolver ? $injector.get(resolve.resolver) : null;
                return {
                    resolve: function(invocables, locals, parent, self) {
                        if (resolver) {
                            return resolver.resolve(invocables, locals, parent, self);
                        }
                        var promises = [];
                        angular.forEach(invocables, function(value) {
                            if (angular.isFunction(value) || angular.isArray(value)) {
                                promises.push($q.resolve($injector.invoke(value)));
                            } else if (angular.isString(value)) {
                                promises.push($q.resolve($injector.get(value)));
                            } else {
                                promises.push($q.resolve(value));
                            }
                        });
                        return $q.all(promises).then(function(resolves) {
                            var resolveObj = {};
                            var resolveIter = 0;
                            angular.forEach(invocables, function(value, key) {
                                resolveObj[key] = resolves[resolveIter++];
                            });
                            return resolveObj;
                        });
                    }
                };
            }];
        })
        .directive('uibModalBackdrop', ['$animateCss', '$injector', '$uibModalStack',
            function($animateCss, $injector, $modalStack) {
                return {
                    replace: true,
                    templateUrl: 'uib/template/modal/backdrop.html',
                    compile: function(tElement, tAttrs) {
                        tElement.addClass(tAttrs.backdropClass);
                        return linkFn;
                    }
                };
    
                function linkFn(scope, element, attrs) {
                    if (attrs.modalInClass) {
                        $animateCss(element, {
                            addClass: attrs.modalInClass
                        }).start();
                        scope.$on($modalStack.NOW_CLOSING_EVENT, function(e, setIsAsync) {
                            var done = setIsAsync();
                            if (scope.modalOptions.animation) {
                                $animateCss(element, {
                                    removeClass: attrs.modalInClass
                                }).start().then(done);
                            } else {
                                done();
                            }
                        });
                    }
                }
            }
        ])
        .directive('uibModalWindow', ['$uibModalStack', '$q', '$animate', '$animateCss', '$document',
            function($modalStack, $q, $animate, $animateCss, $document) {
                return {
                    scope: {
                        index: '@'
                    },
                    replace: true,
                    transclude: true,
                    templateUrl: function(tElement, tAttrs) {
                        return tAttrs.templateUrl || 'uib/template/modal/window.html';
                    },
                    link: function(scope, element, attrs) {
                        element.addClass(attrs.windowClass || '');
                        element.addClass(attrs.windowTopClass || '');
                        scope.size = attrs.size;
                        scope.close = function(evt) {
                            var modal = $modalStack.getTop();
                            if (modal && modal.value.backdrop &&
                                modal.value.backdrop !== 'static' &&
                                evt.target === evt.currentTarget) {
                                evt.preventDefault();
                                evt.stopPropagation();
                                $modalStack.dismiss(modal.key, 'backdrop click');
                            }
                        };
                        element.on('click', scope.close);
                        scope.$isRendered = true;
                        var modalRenderDeferObj = $q.defer();
                        attrs.$observe('modalRender', function(value) {
                            if (value === 'true') {
                                modalRenderDeferObj.resolve();
                            }
                        });
                        modalRenderDeferObj.promise.then(function() {
                            var animationPromise = null;
                            if (attrs.modalInClass) {
                                animationPromise = $animateCss(element, {
                                    addClass: attrs.modalInClass
                                }).start();
                                scope.$on($modalStack.NOW_CLOSING_EVENT, function(e, setIsAsync) {
                                    var done = setIsAsync();
                                    if ($animateCss) {
                                        $animateCss(element, {
                                            removeClass: attrs.modalInClass
                                        }).start().then(done);
                                    } else {
                                        $animate.removeClass(element, attrs.modalInClass).then(done);
                                    }
                                });
                            }
                            $q.when(animationPromise).then(function() {
                                if (!($document[0].activeElement && element[0].contains($document[0].activeElement))) {
                                    var inputWithAutofocus = element[0].querySelector('[autofocus]');
                                    if (inputWithAutofocus) {
                                        inputWithAutofocus.focus();
                                    } else {
                                        element[0].focus();
                                    }
                                }
                            });
                            var modal = $modalStack.getTop();
                            if (modal) {
                                $modalStack.modalRendered(modal.key);
                            }
                        });
                    }
                };
            }
        ])
        .directive('uibModalAnimationClass', function() {
            return {
                compile: function(tElement, tAttrs) {
                    if (tAttrs.modalAnimation) {
                        tElement.addClass(tAttrs.uibModalAnimationClass);
                    }
                }
            };
        })
        .directive('uibModalTransclude', function() {
            return {
                link: function(scope, element, attrs, controller, transclude) {
                    transclude(scope.$parent, function(clone) {
                        element.empty();
                        element.append(clone);
                    });
                }
            };
        })
        .factory('$uibModalStack', ['$animate', '$animateCss', '$document',
            '$compile', '$rootScope', '$q', '$$multiMap', '$$stackedMap',
            function($animate, $animateCss, $document, $compile, $rootScope, $q, $$multiMap, $$stackedMap) {
                var OPENED_MODAL_CLASS = 'modal-open';
                var backdropDomEl, backdropScope;
                var openedWindows = $$stackedMap.createNew();
                var openedClasses = $$multiMap.createNew();
                var $modalStack = {
                    NOW_CLOSING_EVENT: 'modal.stack.now-closing'
                };
                var focusableElementList;
                var focusIndex = 0;
                var tababbleSelector = 'a[href], area[href], input:not([disabled]), ' +
                    'button:not([disabled]),select:not([disabled]), textarea:not([disabled]), ' +
                    'iframe, object, embed, *[tabindex], *[contenteditable=true]';
    
                function backdropIndex() {
                    var topBackdropIndex = -1;
                    var opened = openedWindows.keys();
                    for (var i = 0; i < opened.length; i++) {
                        if (openedWindows.get(opened[i]).value.backdrop) {
                            topBackdropIndex = i;
                        }
                    }
                    return topBackdropIndex;
                }
                $rootScope.$watch(backdropIndex, function(newBackdropIndex) {
                    if (backdropScope) {
                        backdropScope.index = newBackdropIndex;
                    }
                });
    
                function removeModalWindow(modalInstance, elementToReceiveFocus) {
                    var modalWindow = openedWindows.get(modalInstance).value;
                    var appendToElement = modalWindow.appendTo;
                    openedWindows.remove(modalInstance);
                    removeAfterAnimate(modalWindow.modalDomEl, modalWindow.modalScope, function() {
                        var modalBodyClass = modalWindow.openedClass || OPENED_MODAL_CLASS;
                        openedClasses.remove(modalBodyClass, modalInstance);
                        appendToElement.toggleClass(modalBodyClass, openedClasses.hasKey(modalBodyClass));
                        toggleTopWindowClass(true);
                    }, modalWindow.closedDeferred);
                    checkRemoveBackdrop();
                    if (elementToReceiveFocus && elementToReceiveFocus.focus) {
                        elementToReceiveFocus.focus();
                    } else if (appendToElement.focus) {
                        appendToElement.focus();
                    }
                }
    
                function toggleTopWindowClass(toggleSwitch) {
                    var modalWindow;
                    if (openedWindows.length() > 0) {
                        modalWindow = openedWindows.top().value;
                        modalWindow.modalDomEl.toggleClass(modalWindow.windowTopClass || '', toggleSwitch);
                    }
                }
    
                function checkRemoveBackdrop() {
                    if (backdropDomEl && backdropIndex() === -1) {
                        var backdropScopeRef = backdropScope;
                        removeAfterAnimate(backdropDomEl, backdropScope, function() {
                            backdropScopeRef = null;
                        });
                        backdropDomEl = undefined;
                        backdropScope = undefined;
                    }
                }
    
                function removeAfterAnimate(domEl, scope, done, closedDeferred) {
                    var asyncDeferred;
                    var asyncPromise = null;
                    var setIsAsync = function() {
                        if (!asyncDeferred) {
                            asyncDeferred = $q.defer();
                            asyncPromise = asyncDeferred.promise;
                        }
                        return function asyncDone() {
                            asyncDeferred.resolve();
                        };
                    };
                    scope.$broadcast($modalStack.NOW_CLOSING_EVENT, setIsAsync);
                    return $q.when(asyncPromise).then(afterAnimating);
    
                    function afterAnimating() {
                        if (afterAnimating.done) {
                            return;
                        }
                        afterAnimating.done = true;
                        $animateCss(domEl, {
                            event: 'leave'
                        }).start().then(function() {
                            domEl.remove();
                            if (closedDeferred) {
                                closedDeferred.resolve();
                            }
                        });
                        scope.$destroy();
                        if (done) {
                            done();
                        }
                    }
                }
                $document.on('keydown', keydownListener);
                $rootScope.$on('$destroy', function() {
                    $document.off('keydown', keydownListener);
                });
    
                function keydownListener(evt) {
                    if (evt.isDefaultPrevented()) {
                        return evt;
                    }
                    var modal = openedWindows.top();
                    if (modal) {
                        switch (evt.which) {
                            case 27:
                                {
                                    if (modal.value.keyboard) {
                                        evt.preventDefault();
                                        $rootScope.$apply(function() {
                                            $modalStack.dismiss(modal.key, 'escape key press');
                                        });
                                    }
                                    break;
                                }
                            case 9:
                                {
                                    $modalStack.loadFocusElementList(modal);
                                    var focusChanged = false;
                                    if (evt.shiftKey) {
                                        if ($modalStack.isFocusInFirstItem(evt) || $modalStack.isModalFocused(evt, modal)) {
                                            focusChanged = $modalStack.focusLastFocusableElement();
                                        }
                                    } else {
                                        if ($modalStack.isFocusInLastItem(evt)) {
                                            focusChanged = $modalStack.focusFirstFocusableElement();
                                        }
                                    }
                                    if (focusChanged) {
                                        evt.preventDefault();
                                        evt.stopPropagation();
                                    }
                                    break;
                                }
                        }
                    }
                }
                $modalStack.open = function(modalInstance, modal) {
                    var modalOpener = $document[0].activeElement,
                        modalBodyClass = modal.openedClass || OPENED_MODAL_CLASS;
                    toggleTopWindowClass(false);
                    openedWindows.add(modalInstance, {
                        deferred: modal.deferred,
                        renderDeferred: modal.renderDeferred,
                        closedDeferred: modal.closedDeferred,
                        modalScope: modal.scope,
                        backdrop: modal.backdrop,
                        keyboard: modal.keyboard,
                        openedClass: modal.openedClass,
                        windowTopClass: modal.windowTopClass,
                        animation: modal.animation,
                        appendTo: modal.appendTo
                    });
                    openedClasses.put(modalBodyClass, modalInstance);
                    var appendToElement = modal.appendTo,
                        currBackdropIndex = backdropIndex();
                    if (!appendToElement.length) {
                        throw new Error('appendTo element not found. Make sure that the element passed is in DOM.');
                    }
                    if (currBackdropIndex >= 0 && !backdropDomEl) {
                        backdropScope = $rootScope.$new(true);
                        backdropScope.modalOptions = modal;
                        backdropScope.index = currBackdropIndex;
                        backdropDomEl = angular.element('<div uib-modal-backdrop="modal-backdrop"></div>');
                        backdropDomEl.attr('backdrop-class', modal.backdropClass);
                        if (modal.animation) {
                            backdropDomEl.attr('modal-animation', 'true');
                        }
                        $compile(backdropDomEl)(backdropScope);
                        $animate.enter(backdropDomEl, appendToElement);
                    }
                    var angularDomEl = angular.element('<div uib-modal-window="modal-window"></div>');
                    angularDomEl.attr({
                        'template-url': modal.windowTemplateUrl,
                        'window-class': modal.windowClass,
                        'window-top-class': modal.windowTopClass,
                        'size': modal.size,
                        'index': openedWindows.length() - 1,
                        'animate': 'animate'
                    }).html(modal.content);
                    if (modal.animation) {
                        angularDomEl.attr('modal-animation', 'true');
                    }
                    $animate.enter($compile(angularDomEl)(modal.scope), appendToElement)
                        .then(function() {
                            $animate.addClass(appendToElement, modalBodyClass);
                        });
                    openedWindows.top().value.modalDomEl = angularDomEl;
                    openedWindows.top().value.modalOpener = modalOpener;
                    $modalStack.clearFocusListCache();
                };
    
                function broadcastClosing(modalWindow, resultOrReason, closing) {
                    return !modalWindow.value.modalScope.$broadcast('modal.closing', resultOrReason, closing).defaultPrevented;
                }
                $modalStack.close = function(modalInstance, result) {
                    var modalWindow = openedWindows.get(modalInstance);
                    if (modalWindow && broadcastClosing(modalWindow, result, true)) {
                        modalWindow.value.modalScope.$$uibDestructionScheduled = true;
                        modalWindow.value.deferred.resolve(result);
                        removeModalWindow(modalInstance, modalWindow.value.modalOpener);
                        return true;
                    }
                    return !modalWindow;
                };
                $modalStack.dismiss = function(modalInstance, reason) {
                    var modalWindow = openedWindows.get(modalInstance);
                    if (modalWindow && broadcastClosing(modalWindow, reason, false)) {
                        modalWindow.value.modalScope.$$uibDestructionScheduled = true;
                        modalWindow.value.deferred.reject(reason);
                        removeModalWindow(modalInstance, modalWindow.value.modalOpener);
                        return true;
                    }
                    return !modalWindow;
                };
                $modalStack.dismissAll = function(reason) {
                    var topModal = this.getTop();
                    while (topModal && this.dismiss(topModal.key, reason)) {
                        topModal = this.getTop();
                    }
                };
                $modalStack.getTop = function() {
                    return openedWindows.top();
                };
                $modalStack.modalRendered = function(modalInstance) {
                    var modalWindow = openedWindows.get(modalInstance);
                    if (modalWindow) {
                        modalWindow.value.renderDeferred.resolve();
                    }
                };
                $modalStack.focusFirstFocusableElement = function() {
                    if (focusableElementList.length > 0) {
                        focusableElementList[0].focus();
                        return true;
                    }
                    return false;
                };
                $modalStack.focusLastFocusableElement = function() {
                    if (focusableElementList.length > 0) {
                        focusableElementList[focusableElementList.length - 1].focus();
                        return true;
                    }
                    return false;
                };
                $modalStack.isModalFocused = function(evt, modalWindow) {
                    if (evt && modalWindow) {
                        var modalDomEl = modalWindow.value.modalDomEl;
                        if (modalDomEl && modalDomEl.length) {
                            return (evt.target || evt.srcElement) === modalDomEl[0];
                        }
                    }
                    return false;
                };
                $modalStack.isFocusInFirstItem = function(evt) {
                    if (focusableElementList.length > 0) {
                        return (evt.target || evt.srcElement) === focusableElementList[0];
                    }
                    return false;
                };
                $modalStack.isFocusInLastItem = function(evt) {
                    if (focusableElementList.length > 0) {
                        return (evt.target || evt.srcElement) === focusableElementList[focusableElementList.length - 1];
                    }
                    return false;
                };
                $modalStack.clearFocusListCache = function() {
                    focusableElementList = [];
                    focusIndex = 0;
                };
                $modalStack.loadFocusElementList = function(modalWindow) {
                    if (focusableElementList === undefined || !focusableElementList.length) {
                        if (modalWindow) {
                            var modalDomE1 = modalWindow.value.modalDomEl;
                            if (modalDomE1 && modalDomE1.length) {
                                focusableElementList = modalDomE1[0].querySelectorAll(tababbleSelector);
                            }
                        }
                    }
                };
                return $modalStack;
            }
        ])
        .provider('$uibModal', function() {
            var $modalProvider = {
                options: {
                    animation: true,
                    backdrop: true,
                    keyboard: true
                },
                $get: ['$rootScope', '$q', '$document', '$templateRequest', '$controller', '$uibResolve', '$uibModalStack',
                    function($rootScope, $q, $document, $templateRequest, $controller, $uibResolve, $modalStack) {
                        var $modal = {};
    
                        function getTemplatePromise(options) {
                            return options.template ? $q.when(options.template) :
                                $templateRequest(angular.isFunction(options.templateUrl) ?
                                    options.templateUrl() : options.templateUrl);
                        }
                        var promiseChain = null;
                        $modal.getPromiseChain = function() {
                            return promiseChain;
                        };
                        $modal.open = function(modalOptions) {
                            var modalResultDeferred = $q.defer();
                            var modalOpenedDeferred = $q.defer();
                            var modalClosedDeferred = $q.defer();
                            var modalRenderDeferred = $q.defer();
                            var modalInstance = {
                                result: modalResultDeferred.promise,
                                opened: modalOpenedDeferred.promise,
                                closed: modalClosedDeferred.promise,
                                rendered: modalRenderDeferred.promise,
                                close: function(result) {
                                    return $modalStack.close(modalInstance, result);
                                },
                                dismiss: function(reason) {
                                    return $modalStack.dismiss(modalInstance, reason);
                                }
                            };
                            modalOptions = angular.extend({}, $modalProvider.options, modalOptions);
                            modalOptions.resolve = modalOptions.resolve || {};
                            modalOptions.appendTo = modalOptions.appendTo || $document.find('body').eq(0);
                            if (!modalOptions.template && !modalOptions.templateUrl) {
                                throw new Error('One of template or templateUrl options is required.');
                            }
                            var templateAndResolvePromise =
                                $q.all([getTemplatePromise(modalOptions), $uibResolve.resolve(modalOptions.resolve, {}, null, null)]);
    
                            function resolveWithTemplate() {
                                return templateAndResolvePromise;
                            }
                            var samePromise;
                            samePromise = promiseChain = $q.all([promiseChain])
                                .then(resolveWithTemplate, resolveWithTemplate)
                                .then(function resolveSuccess(tplAndVars) {
                                    var providedScope = modalOptions.scope || $rootScope;
                                    var modalScope = providedScope.$new();
                                    modalScope.$close = modalInstance.close;
                                    modalScope.$dismiss = modalInstance.dismiss;
                                    modalScope.$on('$destroy', function() {
                                        if (!modalScope.$$uibDestructionScheduled) {
                                            modalScope.$dismiss('$uibUnscheduledDestruction');
                                        }
                                    });
                                    var ctrlInstance, ctrlLocals = {};
                                    if (modalOptions.controller) {
                                        ctrlLocals.$scope = modalScope;
                                        ctrlLocals.$uibModalInstance = modalInstance;
                                        angular.forEach(tplAndVars[1], function(value, key) {
                                            ctrlLocals[key] = value;
                                        });
                                        ctrlInstance = $controller(modalOptions.controller, ctrlLocals);
                                        if (modalOptions.controllerAs) {
                                            if (modalOptions.bindToController) {
                                                ctrlInstance.$close = modalScope.$close;
                                                ctrlInstance.$dismiss = modalScope.$dismiss;
                                                angular.extend(ctrlInstance, providedScope);
                                            }
                                            modalScope[modalOptions.controllerAs] = ctrlInstance;
                                        }
                                    }
                                    $modalStack.open(modalInstance, {
                                        scope: modalScope,
                                        deferred: modalResultDeferred,
                                        renderDeferred: modalRenderDeferred,
                                        closedDeferred: modalClosedDeferred,
                                        content: tplAndVars[0],
                                        animation: modalOptions.animation,
                                        backdrop: modalOptions.backdrop,
                                        keyboard: modalOptions.keyboard,
                                        backdropClass: modalOptions.backdropClass,
                                        windowTopClass: modalOptions.windowTopClass,
                                        windowClass: modalOptions.windowClass,
                                        windowTemplateUrl: modalOptions.windowTemplateUrl,
                                        size: modalOptions.size,
                                        openedClass: modalOptions.openedClass,
                                        appendTo: modalOptions.appendTo
                                    });
                                    modalOpenedDeferred.resolve(true);
                                }, function resolveError(reason) {
                                    modalOpenedDeferred.reject(reason);
                                    modalResultDeferred.reject(reason);
                                })['finally'](function() {
                                    if (promiseChain === samePromise) {
                                        promiseChain = null;
                                    }
                                });
                            return modalInstance;
                        };
                        return $modal;
                    }
                ]
            };
            return $modalProvider;
        });
    angular.module('ui.bootstrap.paging', [])
        .factory('uibPaging', ['$parse', function($parse) {
            return {
                create: function(ctrl, $scope, $attrs) {
                    ctrl.setNumPages = $attrs.numPages ? $parse($attrs.numPages).assign : angular.noop;
                    ctrl.ngModelCtrl = {
                        $setViewValue: angular.noop
                    };
                    ctrl._watchers = [];
                    ctrl.init = function(ngModelCtrl, config) {
                        ctrl.ngModelCtrl = ngModelCtrl;
                        ctrl.config = config;
                        ngModelCtrl.$render = function() {
                            ctrl.render();
                        };
                        if ($attrs.itemsPerPage) {
                            ctrl._watchers.push($scope.$parent.$watch($parse($attrs.itemsPerPage), function(value) {
                                ctrl.itemsPerPage = parseInt(value, 10);
                                $scope.totalPages = ctrl.calculateTotalPages();
                                ctrl.updatePage();
                            }));
                        } else {
                            ctrl.itemsPerPage = config.itemsPerPage;
                        }
                        $scope.$watch('totalItems', function(newTotal, oldTotal) {
                            if (angular.isDefined(newTotal) || newTotal !== oldTotal) {
                                $scope.totalPages = ctrl.calculateTotalPages();
                                ctrl.updatePage();
                            }
                        });
                    };
                    ctrl.calculateTotalPages = function() {
                        var totalPages = ctrl.itemsPerPage < 1 ? 1 : Math.ceil($scope.totalItems / ctrl.itemsPerPage);
                        return Math.max(totalPages || 0, 1);
                    };
                    ctrl.render = function() {
                        $scope.page = parseInt(ctrl.ngModelCtrl.$viewValue, 10) || 1;
                    };
                    $scope.selectPage = function(page, evt) {
                        if (evt) {
                            evt.preventDefault();
                        }
                        var clickAllowed = !$scope.ngDisabled || !evt;
                        if (clickAllowed && $scope.page !== page && page > 0 && page <= $scope.totalPages) {
                            if (evt && evt.target) {
                                evt.target.blur();
                            }
                            ctrl.ngModelCtrl.$setViewValue(page);
                            ctrl.ngModelCtrl.$render();
                        }
                    };
                    $scope.getText = function(key) {
                        return $scope[key + 'Text'] || ctrl.config[key + 'Text'];
                    };
                    $scope.noPrevious = function() {
                        return $scope.page === 1;
                    };
                    $scope.noNext = function() {
                        return $scope.page === $scope.totalPages;
                    };
                    ctrl.updatePage = function() {
                        ctrl.setNumPages($scope.$parent, $scope.totalPages);
                        if ($scope.page > $scope.totalPages) {
                            $scope.selectPage($scope.totalPages);
                        } else {
                            ctrl.ngModelCtrl.$render();
                        }
                    };
                    $scope.$on('$destroy', function() {
                        while (ctrl._watchers.length) {
                            ctrl._watchers.shift()();
                        }
                    });
                }
            };
        }]);
    angular.module('ui.bootstrap.pager', ['ui.bootstrap.paging'])
        .controller('UibPagerController', ['$scope', '$attrs', 'uibPaging', 'uibPagerConfig', function($scope, $attrs, uibPaging, uibPagerConfig) {
            $scope.align = angular.isDefined($attrs.align) ? $scope.$parent.$eval($attrs.align) : uibPagerConfig.align;
            uibPaging.create(this, $scope, $attrs);
        }])
        .constant('uibPagerConfig', {
            itemsPerPage: 10,
            previousText: '« Previous',
            nextText: 'Next »',
            align: true
        })
        .directive('uibPager', ['uibPagerConfig', function(uibPagerConfig) {
            return {
                scope: {
                    totalItems: '=',
                    previousText: '@',
                    nextText: '@',
                    ngDisabled: '='
                },
                require: ['uibPager', '?ngModel'],
                controller: 'UibPagerController',
                controllerAs: 'pager',
                templateUrl: function(element, attrs) {
                    return attrs.templateUrl || 'uib/template/pager/pager.html';
                },
                replace: true,
                link: function(scope, element, attrs, ctrls) {
                    var paginationCtrl = ctrls[0],
                        ngModelCtrl = ctrls[1];
                    if (!ngModelCtrl) {
                        return;
                    }
                    paginationCtrl.init(ngModelCtrl, uibPagerConfig);
                }
            };
        }]);
    angular.module('ui.bootstrap.pagination', ['ui.bootstrap.paging'])
        .controller('UibPaginationController', ['$scope', '$attrs', '$parse', 'uibPaging', 'uibPaginationConfig', function($scope, $attrs, $parse, uibPaging, uibPaginationConfig) {
            var ctrl = this;
            var maxSize = angular.isDefined($attrs.maxSize) ? $scope.$parent.$eval($attrs.maxSize) : uibPaginationConfig.maxSize,
                rotate = angular.isDefined($attrs.rotate) ? $scope.$parent.$eval($attrs.rotate) : uibPaginationConfig.rotate,
                forceEllipses = angular.isDefined($attrs.forceEllipses) ? $scope.$parent.$eval($attrs.forceEllipses) : uibPaginationConfig.forceEllipses,
                boundaryLinkNumbers = angular.isDefined($attrs.boundaryLinkNumbers) ? $scope.$parent.$eval($attrs.boundaryLinkNumbers) : uibPaginationConfig.boundaryLinkNumbers;
            $scope.boundaryLinks = angular.isDefined($attrs.boundaryLinks) ? $scope.$parent.$eval($attrs.boundaryLinks) : uibPaginationConfig.boundaryLinks;
            $scope.directionLinks = angular.isDefined($attrs.directionLinks) ? $scope.$parent.$eval($attrs.directionLinks) : uibPaginationConfig.directionLinks;
            uibPaging.create(this, $scope, $attrs);
            if ($attrs.maxSize) {
                ctrl._watchers.push($scope.$parent.$watch($parse($attrs.maxSize), function(value) {
                    maxSize = parseInt(value, 10);
                    ctrl.render();
                }));
            }
    
            function makePage(number, text, isActive) {
                return {
                    number: number,
                    text: text,
                    active: isActive
                };
            }
    
            function getPages(currentPage, totalPages) {
                var pages = [];
                var startPage = 1,
                    endPage = totalPages;
                var isMaxSized = angular.isDefined(maxSize) && maxSize < totalPages;
                if (isMaxSized) {
                    if (rotate) {
                        startPage = Math.max(currentPage - Math.floor(maxSize / 2), 1);
                        endPage = startPage + maxSize - 1;
                        if (endPage > totalPages) {
                            endPage = totalPages;
                            startPage = endPage - maxSize + 1;
                        }
                    } else {
                        startPage = (Math.ceil(currentPage / maxSize) - 1) * maxSize + 1;
                        endPage = Math.min(startPage + maxSize - 1, totalPages);
                    }
                }
                for (var number = startPage; number <= endPage; number++) {
                    var page = makePage(number, number, number === currentPage);
                    pages.push(page);
                }
                if (isMaxSized && maxSize > 0 && (!rotate || forceEllipses || boundaryLinkNumbers)) {
                    if (startPage > 1) {
                        if (!boundaryLinkNumbers || startPage > 3) {
                            var previousPageSet = makePage(startPage - 1, '...', false);
                            pages.unshift(previousPageSet);
                        }
                        if (boundaryLinkNumbers) {
                            if (startPage === 3) {
                                var secondPageLink = makePage(2, '2', false);
                                pages.unshift(secondPageLink);
                            }
                            var firstPageLink = makePage(1, '1', false);
                            pages.unshift(firstPageLink);
                        }
                    }
                    if (endPage < totalPages) {
                        if (!boundaryLinkNumbers || endPage < totalPages - 2) {
                            var nextPageSet = makePage(endPage + 1, '...', false);
                            pages.push(nextPageSet);
                        }
                        if (boundaryLinkNumbers) {
                            if (endPage === totalPages - 2) {
                                var secondToLastPageLink = makePage(totalPages - 1, totalPages - 1, false);
                                pages.push(secondToLastPageLink);
                            }
                            var lastPageLink = makePage(totalPages, totalPages, false);
                            pages.push(lastPageLink);
                        }
                    }
                }
                return pages;
            }
            var originalRender = this.render;
            this.render = function() {
                originalRender();
                if ($scope.page > 0 && $scope.page <= $scope.totalPages) {
                    $scope.pages = getPages($scope.page, $scope.totalPages);
                }
            };
        }])
        .constant('uibPaginationConfig', {
            itemsPerPage: 10,
            boundaryLinks: false,
            boundaryLinkNumbers: false,
            directionLinks: true,
            firstText: 'First',
            previousText: 'Previous',
            nextText: 'Next',
            lastText: 'Last',
            rotate: true,
            forceEllipses: false
        })
        .directive('uibPagination', ['$parse', 'uibPaginationConfig', function($parse, uibPaginationConfig) {
            return {
                scope: {
                    totalItems: '=',
                    firstText: '@',
                    previousText: '@',
                    nextText: '@',
                    lastText: '@',
                    ngDisabled: '='
                },
                require: ['uibPagination', '?ngModel'],
                controller: 'UibPaginationController',
                controllerAs: 'pagination',
                templateUrl: function(element, attrs) {
                    return attrs.templateUrl || 'uib/template/pagination/pagination.html';
                },
                replace: true,
                link: function(scope, element, attrs, ctrls) {
                    var paginationCtrl = ctrls[0],
                        ngModelCtrl = ctrls[1];
                    if (!ngModelCtrl) {
                        return;
                    }
                    paginationCtrl.init(ngModelCtrl, uibPaginationConfig);
                }
            };
        }]);
    angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.stackedMap'])
        .provider('$uibTooltip', function() {
            var defaultOptions = {
                placement: 'top',
                placementClassPrefix: '',
                animation: true,
                popupDelay: 0,
                popupCloseDelay: 0,
                useContentExp: false
            };
            var triggerMap = {
                'mouseenter': 'mouseleave',
                'click': 'click',
                'outsideClick': 'outsideClick',
                'focus': 'blur',
                'none': ''
            };
            var globalOptions = {};
            this.options = function(value) {
                angular.extend(globalOptions, value);
            };
            this.setTriggers = function setTriggers(triggers) {
                angular.extend(triggerMap, triggers);
            };
    
            function snake_case(name) {
                var regexp = /[A-Z]/g;
                var separator = '-';
                return name.replace(regexp, function(letter, pos) {
                    return (pos ? separator : '') + letter.toLowerCase();
                });
            }
            this.$get = ['$window', '$compile', '$timeout', '$document', '$uibPosition', '$interpolate', '$rootScope', '$parse', '$$stackedMap', function($window, $compile, $timeout, $document, $position, $interpolate, $rootScope, $parse, $$stackedMap) {
                var openedTooltips = $$stackedMap.createNew();
                $document.on('keypress', keypressListener);
                $rootScope.$on('$destroy', function() {
                    $document.off('keypress', keypressListener);
                });
    
                function keypressListener(e) {
                    if (e.which === 27) {
                        var last = openedTooltips.top();
                        if (last) {
                            last.value.close();
                            openedTooltips.removeTop();
                            last = null;
                        }
                    }
                }
                return function $tooltip(ttType, prefix, defaultTriggerShow, options) {
                    options = angular.extend({}, defaultOptions, globalOptions, options);
    
                    function getTriggers(trigger) {
                        var show = (trigger || options.trigger || defaultTriggerShow).split(' ');
                        var hide = show.map(function(trigger) {
                            return triggerMap[trigger] || trigger;
                        });
                        return {
                            show: show,
                            hide: hide
                        };
                    }
                    var directiveName = snake_case(ttType);
                    var startSym = $interpolate.startSymbol();
                    var endSym = $interpolate.endSymbol();
                    var template =
                        '<div ' + directiveName + '-popup ' +
                        'title="' + startSym + 'title' + endSym + '" ' +
                        (options.useContentExp ?
                            'content-exp="contentExp()" ' :
                            'content="' + startSym + 'content' + endSym + '" ') +
                        'placement="' + startSym + 'placement' + endSym + '" ' +
                        'popup-class="' + startSym + 'popupClass' + endSym + '" ' +
                        'animation="animation" ' +
                        'is-open="isOpen"' +
                        'origin-scope="origScope" ' +
                        'style="visibility: hidden; display: block; top: -9999px; left: -9999px;"' +
                        '>' +
                        '</div>';
                    return {
                        compile: function(tElem, tAttrs) {
                            var tooltipLinker = $compile(template);
                            return function link(scope, element, attrs, tooltipCtrl) {
                                var tooltip;
                                var tooltipLinkedScope;
                                var transitionTimeout;
                                var showTimeout;
                                var hideTimeout;
                                var positionTimeout;
                                var appendToBody = angular.isDefined(options.appendToBody) ? options.appendToBody : false;
                                var triggers = getTriggers(undefined);
                                var hasEnableExp = angular.isDefined(attrs[prefix + 'Enable']);
                                var ttScope = scope.$new(true);
                                var repositionScheduled = false;
                                var isOpenParse = angular.isDefined(attrs[prefix + 'IsOpen']) ? $parse(attrs[prefix + 'IsOpen']) : false;
                                var contentParse = options.useContentExp ? $parse(attrs[ttType]) : false;
                                var observers = [];
                                var positionTooltip = function() {
                                    if (!tooltip || !tooltip.html()) {
                                        return;
                                    }
                                    if (!positionTimeout) {
                                        positionTimeout = $timeout(function() {
                                            tooltip.css({
                                                top: 0,
                                                left: 0
                                            });
                                            var ttPosition = $position.positionElements(element, tooltip, ttScope.placement, appendToBody);
                                            tooltip.css({
                                                top: ttPosition.top + 'px',
                                                left: ttPosition.left + 'px',
                                                visibility: 'visible'
                                            });
                                            if (options.placementClassPrefix) {
                                                tooltip.removeClass('top bottom left right');
                                            }
                                            tooltip.removeClass(
                                                options.placementClassPrefix + 'top ' +
                                                options.placementClassPrefix + 'top-left ' +
                                                options.placementClassPrefix + 'top-right ' +
                                                options.placementClassPrefix + 'bottom ' +
                                                options.placementClassPrefix + 'bottom-left ' +
                                                options.placementClassPrefix + 'bottom-right ' +
                                                options.placementClassPrefix + 'left ' +
                                                options.placementClassPrefix + 'left-top ' +
                                                options.placementClassPrefix + 'left-bottom ' +
                                                options.placementClassPrefix + 'right ' +
                                                options.placementClassPrefix + 'right-top ' +
                                                options.placementClassPrefix + 'right-bottom');
                                            var placement = ttPosition.placement.split('-');
                                            tooltip.addClass(placement[0] + ' ' + options.placementClassPrefix + ttPosition.placement);
                                            $position.positionArrow(tooltip, ttPosition.placement);
                                            positionTimeout = null;
                                        }, 0, false);
                                    }
                                };
                                ttScope.origScope = scope;
                                ttScope.isOpen = false;
                                openedTooltips.add(ttScope, {
                                    close: hide
                                });
    
                                function toggleTooltipBind() {
                                    if (!ttScope.isOpen) {
                                        showTooltipBind();
                                    } else {
                                        hideTooltipBind();
                                    }
                                }
    
                                function showTooltipBind() {
                                    if (hasEnableExp && !scope.$eval(attrs[prefix + 'Enable'])) {
                                        return;
                                    }
                                    cancelHide();
                                    prepareTooltip();
                                    if (ttScope.popupDelay) {
                                        if (!showTimeout) {
                                            showTimeout = $timeout(show, ttScope.popupDelay, false);
                                        }
                                    } else {
                                        show();
                                    }
                                }
    
                                function hideTooltipBind() {
                                    cancelShow();
                                    if (ttScope.popupCloseDelay) {
                                        if (!hideTimeout) {
                                            hideTimeout = $timeout(hide, ttScope.popupCloseDelay, false);
                                        }
                                    } else {
                                        hide();
                                    }
                                }
    
                                function show() {
                                    cancelShow();
                                    cancelHide();
                                    if (!ttScope.content) {
                                        return angular.noop;
                                    }
                                    createTooltip();
                                    ttScope.$evalAsync(function() {
                                        ttScope.isOpen = true;
                                        assignIsOpen(true);
                                        positionTooltip();
                                    });
                                }
    
                                function cancelShow() {
                                    if (showTimeout) {
                                        $timeout.cancel(showTimeout);
                                        showTimeout = null;
                                    }
                                    if (positionTimeout) {
                                        $timeout.cancel(positionTimeout);
                                        positionTimeout = null;
                                    }
                                }
    
                                function hide() {
                                    if (!ttScope) {
                                        return;
                                    }
                                    ttScope.$evalAsync(function() {
                                        if (ttScope) {
                                            ttScope.isOpen = false;
                                            assignIsOpen(false);
                                            if (ttScope.animation) {
                                                if (!transitionTimeout) {
                                                    transitionTimeout = $timeout(removeTooltip, 150, false);
                                                }
                                            } else {
                                                removeTooltip();
                                            }
                                        }
                                    });
                                }
    
                                function cancelHide() {
                                    if (hideTimeout) {
                                        $timeout.cancel(hideTimeout);
                                        hideTimeout = null;
                                    }
                                    if (transitionTimeout) {
                                        $timeout.cancel(transitionTimeout);
                                        transitionTimeout = null;
                                    }
                                }
    
                                function createTooltip() {
                                    if (tooltip) {
                                        return;
                                    }
                                    tooltipLinkedScope = ttScope.$new();
                                    tooltip = tooltipLinker(tooltipLinkedScope, function(tooltip) {
                                        if (appendToBody) {
                                            $document.find('body').append(tooltip);
                                        } else {
                                            element.after(tooltip);
                                        }
                                    });
                                    prepObservers();
                                }
    
                                function removeTooltip() {
                                    cancelShow();
                                    cancelHide();
                                    unregisterObservers();
                                    if (tooltip) {
                                        tooltip.remove();
                                        tooltip = null;
                                    }
                                    if (tooltipLinkedScope) {
                                        tooltipLinkedScope.$destroy();
                                        tooltipLinkedScope = null;
                                    }
                                }
    
                                function prepareTooltip() {
                                    ttScope.title = attrs[prefix + 'Title'];
                                    if (contentParse) {
                                        ttScope.content = contentParse(scope);
                                    } else {
                                        ttScope.content = attrs[ttType];
                                    }
                                    ttScope.popupClass = attrs[prefix + 'Class'];
                                    ttScope.placement = angular.isDefined(attrs[prefix + 'Placement']) ? attrs[prefix + 'Placement'] : options.placement;
                                    var delay = parseInt(attrs[prefix + 'PopupDelay'], 10);
                                    var closeDelay = parseInt(attrs[prefix + 'PopupCloseDelay'], 10);
                                    ttScope.popupDelay = !isNaN(delay) ? delay : options.popupDelay;
                                    ttScope.popupCloseDelay = !isNaN(closeDelay) ? closeDelay : options.popupCloseDelay;
                                }
    
                                function assignIsOpen(isOpen) {
                                    if (isOpenParse && angular.isFunction(isOpenParse.assign)) {
                                        isOpenParse.assign(scope, isOpen);
                                    }
                                }
                                ttScope.contentExp = function() {
                                    return ttScope.content;
                                };
                                attrs.$observe('disabled', function(val) {
                                    if (val) {
                                        cancelShow();
                                    }
                                    if (val && ttScope.isOpen) {
                                        hide();
                                    }
                                });
                                if (isOpenParse) {
                                    scope.$watch(isOpenParse, function(val) {
                                        if (ttScope && !val === ttScope.isOpen) {
                                            toggleTooltipBind();
                                        }
                                    });
                                }
    
                                function prepObservers() {
                                    observers.length = 0;
                                    if (contentParse) {
                                        observers.push(
                                            scope.$watch(contentParse, function(val) {
                                                ttScope.content = val;
                                                if (!val && ttScope.isOpen) {
                                                    hide();
                                                }
                                            })
                                        );
                                        observers.push(
                                            tooltipLinkedScope.$watch(function() {
                                                if (!repositionScheduled) {
                                                    repositionScheduled = true;
                                                    tooltipLinkedScope.$$postDigest(function() {
                                                        repositionScheduled = false;
                                                        if (ttScope && ttScope.isOpen) {
                                                            positionTooltip();
                                                        }
                                                    });
                                                }
                                            })
                                        );
                                    } else {
                                        observers.push(
                                            attrs.$observe(ttType, function(val) {
                                                ttScope.content = val;
                                                if (!val && ttScope.isOpen) {
                                                    hide();
                                                } else {
                                                    positionTooltip();
                                                }
                                            })
                                        );
                                    }
                                    observers.push(
                                        attrs.$observe(prefix + 'Title', function(val) {
                                            ttScope.title = val;
                                            if (ttScope.isOpen) {
                                                positionTooltip();
                                            }
                                        })
                                    );
                                    observers.push(
                                        attrs.$observe(prefix + 'Placement', function(val) {
                                            ttScope.placement = val ? val : options.placement;
                                            if (ttScope.isOpen) {
                                                positionTooltip();
                                            }
                                        })
                                    );
                                }
    
                                function unregisterObservers() {
                                    if (observers.length) {
                                        angular.forEach(observers, function(observer) {
                                            observer();
                                        });
                                        observers.length = 0;
                                    }
                                }
    
                                function bodyHideTooltipBind(e) {
                                    if (!ttScope || !ttScope.isOpen || !tooltip) {
                                        return;
                                    }
                                    if (!element[0].contains(e.target) && !tooltip[0].contains(e.target)) {
                                        hideTooltipBind();
                                    }
                                }
                                var unregisterTriggers = function() {
                                    triggers.show.forEach(function(trigger) {
                                        if (trigger === 'outsideClick') {
                                            element.off('click', toggleTooltipBind);
                                        } else {
                                            element.off(trigger, showTooltipBind);
                                            element.off(trigger, toggleTooltipBind);
                                        }
                                    });
                                    triggers.hide.forEach(function(trigger) {
                                        if (trigger === 'outsideClick') {
                                            $document.off('click', bodyHideTooltipBind);
                                        } else {
                                            element.off(trigger, hideTooltipBind);
                                        }
                                    });
                                };
    
                                function prepTriggers() {
                                    var val = attrs[prefix + 'Trigger'];
                                    unregisterTriggers();
                                    triggers = getTriggers(val);
                                    if (triggers.show !== 'none') {
                                        triggers.show.forEach(function(trigger, idx) {
                                            if (trigger === 'outsideClick') {
                                                element.on('click', toggleTooltipBind);
                                                $document.on('click', bodyHideTooltipBind);
                                            } else if (trigger === triggers.hide[idx]) {
                                                element.on(trigger, toggleTooltipBind);
                                            } else if (trigger) {
                                                element.on(trigger, showTooltipBind);
                                                element.on(triggers.hide[idx], hideTooltipBind);
                                            }
                                            element.on('keypress', function(e) {
                                                if (e.which === 27) {
                                                    hideTooltipBind();
                                                }
                                            });
                                        });
                                    }
                                }
                                prepTriggers();
                                var animation = scope.$eval(attrs[prefix + 'Animation']);
                                ttScope.animation = angular.isDefined(animation) ? !!animation : options.animation;
                                var appendToBodyVal;
                                var appendKey = prefix + 'AppendToBody';
                                if (appendKey in attrs && attrs[appendKey] === undefined) {
                                    appendToBodyVal = true;
                                } else {
                                    appendToBodyVal = scope.$eval(attrs[appendKey]);
                                }
                                appendToBody = angular.isDefined(appendToBodyVal) ? appendToBodyVal : appendToBody;
                                scope.$on('$destroy', function onDestroyTooltip() {
                                    unregisterTriggers();
                                    removeTooltip();
                                    openedTooltips.remove(ttScope);
                                    ttScope = null;
                                });
                            };
                        }
                    };
                };
            }];
        })
        .directive('uibTooltipTemplateTransclude', [
            '$animate', '$sce', '$compile', '$templateRequest',
            function($animate, $sce, $compile, $templateRequest) {
                return {
                    link: function(scope, elem, attrs) {
                        var origScope = scope.$eval(attrs.tooltipTemplateTranscludeScope);
                        var changeCounter = 0,
                            currentScope,
                            previousElement,
                            currentElement;
                        var cleanupLastIncludeContent = function() {
                            if (previousElement) {
                                previousElement.remove();
                                previousElement = null;
                            }
                            if (currentScope) {
                                currentScope.$destroy();
                                currentScope = null;
                            }
                            if (currentElement) {
                                $animate.leave(currentElement).then(function() {
                                    previousElement = null;
                                });
                                previousElement = currentElement;
                                currentElement = null;
                            }
                        };
                        scope.$watch($sce.parseAsResourceUrl(attrs.uibTooltipTemplateTransclude), function(src) {
                            var thisChangeId = ++changeCounter;
                            if (src) {
                                $templateRequest(src, true).then(function(response) {
                                    if (thisChangeId !== changeCounter) {
                                        return;
                                    }
                                    var newScope = origScope.$new();
                                    var template = response;
                                    var clone = $compile(template)(newScope, function(clone) {
                                        cleanupLastIncludeContent();
                                        $animate.enter(clone, elem);
                                    });
                                    currentScope = newScope;
                                    currentElement = clone;
                                    currentScope.$emit('$includeContentLoaded', src);
                                }, function() {
                                    if (thisChangeId === changeCounter) {
                                        cleanupLastIncludeContent();
                                        scope.$emit('$includeContentError', src);
                                    }
                                });
                                scope.$emit('$includeContentRequested', src);
                            } else {
                                cleanupLastIncludeContent();
                            }
                        });
                        scope.$on('$destroy', cleanupLastIncludeContent);
                    }
                };
            }
        ])
        .directive('uibTooltipClasses', ['$uibPosition', function($uibPosition) {
            return {
                restrict: 'A',
                link: function(scope, element, attrs) {
                    if (scope.placement) {
                        var position = $uibPosition.parsePlacement(scope.placement);
                        element.addClass(position[0]);
                    } else {
                        element.addClass('top');
                    }
                    if (scope.popupClass) {
                        element.addClass(scope.popupClass);
                    }
                    if (scope.animation()) {
                        element.addClass(attrs.tooltipAnimationClass);
                    }
                }
            };
        }])
        .directive('uibTooltipPopup', function() {
            return {
                replace: true,
                scope: {
                    content: '@',
                    placement: '@',
                    popupClass: '@',
                    animation: '&',
                    isOpen: '&'
                },
                templateUrl: 'uib/template/tooltip/tooltip-popup.html'
            };
        })
        .directive('uibTooltip', ['$uibTooltip', function($uibTooltip) {
            return $uibTooltip('uibTooltip', 'tooltip', 'mouseenter');
        }])
        .directive('uibTooltipTemplatePopup', function() {
            return {
                replace: true,
                scope: {
                    contentExp: '&',
                    placement: '@',
                    popupClass: '@',
                    animation: '&',
                    isOpen: '&',
                    originScope: '&'
                },
                templateUrl: 'uib/template/tooltip/tooltip-template-popup.html'
            };
        })
        .directive('uibTooltipTemplate', ['$uibTooltip', function($uibTooltip) {
            return $uibTooltip('uibTooltipTemplate', 'tooltip', 'mouseenter', {
                useContentExp: true
            });
        }])
        .directive('uibTooltipHtmlPopup', function() {
            return {
                replace: true,
                scope: {
                    contentExp: '&',
                    placement: '@',
                    popupClass: '@',
                    animation: '&',
                    isOpen: '&'
                },
                templateUrl: 'uib/template/tooltip/tooltip-html-popup.html'
            };
        })
        .directive('uibTooltipHtml', ['$uibTooltip', function($uibTooltip) {
            return $uibTooltip('uibTooltipHtml', 'tooltip', 'mouseenter', {
                useContentExp: true
            });
        }]);
    angular.module('ui.bootstrap.popover', ['ui.bootstrap.tooltip'])
        .directive('uibPopoverTemplatePopup', function() {
            return {
                replace: true,
                scope: {
                    title: '@',
                    contentExp: '&',
                    placement: '@',
                    popupClass: '@',
                    animation: '&',
                    isOpen: '&',
                    originScope: '&'
                },
                templateUrl: 'uib/template/popover/popover-template.html'
            };
        })
        .directive('uibPopoverTemplate', ['$uibTooltip', function($uibTooltip) {
            return $uibTooltip('uibPopoverTemplate', 'popover', 'click', {
                useContentExp: true
            });
        }])
        .directive('uibPopoverHtmlPopup', function() {
            return {
                replace: true,
                scope: {
                    contentExp: '&',
                    title: '@',
                    placement: '@',
                    popupClass: '@',
                    animation: '&',
                    isOpen: '&'
                },
                templateUrl: 'uib/template/popover/popover-html.html'
            };
        })
        .directive('uibPopoverHtml', ['$uibTooltip', function($uibTooltip) {
            return $uibTooltip('uibPopoverHtml', 'popover', 'click', {
                useContentExp: true
            });
        }])
        .directive('uibPopoverPopup', function() {
            return {
                replace: true,
                scope: {
                    title: '@',
                    content: '@',
                    placement: '@',
                    popupClass: '@',
                    animation: '&',
                    isOpen: '&'
                },
                templateUrl: 'uib/template/popover/popover.html'
            };
        })
        .directive('uibPopover', ['$uibTooltip', function($uibTooltip) {
            return $uibTooltip('uibPopover', 'popover', 'click');
        }]);
    angular.module('ui.bootstrap.progressbar', [])
        .constant('uibProgressConfig', {
            animate: true,
            max: 100
        })
        .controller('UibProgressController', ['$scope', '$attrs', 'uibProgressConfig', function($scope, $attrs, progressConfig) {
            var self = this,
                animate = angular.isDefined($attrs.animate) ? $scope.$parent.$eval($attrs.animate) : progressConfig.animate;
            this.bars = [];
            $scope.max = angular.isDefined($scope.max) ? $scope.max : progressConfig.max;
            this.addBar = function(bar, element, attrs) {
                if (!animate) {
                    element.css({
                        'transition': 'none'
                    });
                }
                this.bars.push(bar);
                bar.max = $scope.max;
                bar.title = attrs && angular.isDefined(attrs.title) ? attrs.title : 'progressbar';
                bar.$watch('value', function(value) {
                    bar.recalculatePercentage();
                });
                bar.recalculatePercentage = function() {
                    var totalPercentage = self.bars.reduce(function(total, bar) {
                        bar.percent = +(100 * bar.value / bar.max).toFixed(2);
                        return total + bar.percent;
                    }, 0);
                    if (totalPercentage > 100) {
                        bar.percent -= totalPercentage - 100;
                    }
                };
                bar.$on('$destroy', function() {
                    element = null;
                    self.removeBar(bar);
                });
            };
            this.removeBar = function(bar) {
                this.bars.splice(this.bars.indexOf(bar), 1);
                this.bars.forEach(function(bar) {
                    bar.recalculatePercentage();
                });
            };
            $scope.$watch('max', function(max) {
                self.bars.forEach(function(bar) {
                    bar.max = $scope.max;
                    bar.recalculatePercentage();
                });
            });
        }])
        .directive('uibProgress', function() {
            return {
                replace: true,
                transclude: true,
                controller: 'UibProgressController',
                require: 'uibProgress',
                scope: {
                    max: '=?'
                },
                templateUrl: 'uib/template/progressbar/progress.html'
            };
        })
        .directive('uibBar', function() {
            return {
                replace: true,
                transclude: true,
                require: '^uibProgress',
                scope: {
                    value: '=',
                    type: '@'
                },
                templateUrl: 'uib/template/progressbar/bar.html',
                link: function(scope, element, attrs, progressCtrl) {
                    progressCtrl.addBar(scope, element, attrs);
                }
            };
        })
        .directive('uibProgressbar', function() {
            return {
                replace: true,
                transclude: true,
                controller: 'UibProgressController',
                scope: {
                    value: '=',
                    max: '=?',
                    type: '@'
                },
                templateUrl: 'uib/template/progressbar/progressbar.html',
                link: function(scope, element, attrs, progressCtrl) {
                    progressCtrl.addBar(scope, angular.element(element.children()[0]), {
                        title: attrs.title
                    });
                }
            };
        });
    angular.module('ui.bootstrap.rating', [])
        .constant('uibRatingConfig', {
            max: 5,
            stateOn: null,
            stateOff: null,
            titles: ['one', 'two', 'three', 'four', 'five']
        })
        .controller('UibRatingController', ['$scope', '$attrs', 'uibRatingConfig', function($scope, $attrs, ratingConfig) {
            var ngModelCtrl = {
                $setViewValue: angular.noop
            };
            this.init = function(ngModelCtrl_) {
                ngModelCtrl = ngModelCtrl_;
                ngModelCtrl.$render = this.render;
                ngModelCtrl.$formatters.push(function(value) {
                    if (angular.isNumber(value) && value << 0 !== value) {
                        value = Math.round(value);
                    }
                    return value;
                });
                this.stateOn = angular.isDefined($attrs.stateOn) ? $scope.$parent.$eval($attrs.stateOn) : ratingConfig.stateOn;
                this.stateOff = angular.isDefined($attrs.stateOff) ? $scope.$parent.$eval($attrs.stateOff) : ratingConfig.stateOff;
                var tmpTitles = angular.isDefined($attrs.titles) ? $scope.$parent.$eval($attrs.titles) : ratingConfig.titles;
                this.titles = angular.isArray(tmpTitles) && tmpTitles.length > 0 ?
                    tmpTitles : ratingConfig.titles;
                var ratingStates = angular.isDefined($attrs.ratingStates) ?
                    $scope.$parent.$eval($attrs.ratingStates) :
                    new Array(angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : ratingConfig.max);
                $scope.range = this.buildTemplateObjects(ratingStates);
            };
            this.buildTemplateObjects = function(states) {
                for (var i = 0, n = states.length; i < n; i++) {
                    states[i] = angular.extend({
                        index: i
                    }, {
                        stateOn: this.stateOn,
                        stateOff: this.stateOff,
                        title: this.getTitle(i)
                    }, states[i]);
                }
                return states;
            };
            this.getTitle = function(index) {
                if (index >= this.titles.length) {
                    return index + 1;
                }
                return this.titles[index];
            };
            $scope.rate = function(value) {
                if (!$scope.readonly && value >= 0 && value <= $scope.range.length) {
                    ngModelCtrl.$setViewValue(ngModelCtrl.$viewValue === value ? 0 : value);
                    ngModelCtrl.$render();
                }
            };
            $scope.enter = function(value) {
                if (!$scope.readonly) {
                    $scope.value = value;
                }
                $scope.onHover({
                    value: value
                });
            };
            $scope.reset = function() {
                $scope.value = ngModelCtrl.$viewValue;
                $scope.onLeave();
            };
            $scope.onKeydown = function(evt) {
                if (/(37|38|39|40)/.test(evt.which)) {
                    evt.preventDefault();
                    evt.stopPropagation();
                    $scope.rate($scope.value + (evt.which === 38 || evt.which === 39 ? 1 : -1));
                }
            };
            this.render = function() {
                $scope.value = ngModelCtrl.$viewValue;
            };
        }])
        .directive('uibRating', function() {
            return {
                require: ['uibRating', 'ngModel'],
                scope: {
                    readonly: '=?',
                    onHover: '&',
                    onLeave: '&'
                },
                controller: 'UibRatingController',
                templateUrl: 'uib/template/rating/rating.html',
                replace: true,
                link: function(scope, element, attrs, ctrls) {
                    var ratingCtrl = ctrls[0],
                        ngModelCtrl = ctrls[1];
                    ratingCtrl.init(ngModelCtrl);
                }
            };
        });
    angular.module('ui.bootstrap.tabs', [])
        .controller('UibTabsetController', ['$scope', function($scope) {
            var ctrl = this,
                tabs = ctrl.tabs = $scope.tabs = [];
            ctrl.select = function(selectedTab) {
                angular.forEach(tabs, function(tab) {
                    if (tab.active && tab !== selectedTab) {
                        tab.active = false;
                        tab.onDeselect();
                        selectedTab.selectCalled = false;
                    }
                });
                selectedTab.active = true;
                if (!selectedTab.selectCalled) {
                    selectedTab.onSelect();
                    selectedTab.selectCalled = true;
                }
            };
            ctrl.addTab = function addTab(tab) {
                tabs.push(tab);
                if (tabs.length === 1 && tab.active !== false) {
                    tab.active = true;
                } else if (tab.active) {
                    ctrl.select(tab);
                } else {
                    tab.active = false;
                }
            };
            ctrl.removeTab = function removeTab(tab) {
                var index = tabs.indexOf(tab);
                if (tab.active && tabs.length > 1 && !destroyed) {
                    var newActiveIndex = index === tabs.length - 1 ? index - 1 : index + 1;
                    ctrl.select(tabs[newActiveIndex]);
                }
                tabs.splice(index, 1);
            };
            var destroyed;
            $scope.$on('$destroy', function() {
                destroyed = true;
            });
        }])
        .directive('uibTabset', function() {
            return {
                transclude: true,
                replace: true,
                scope: {
                    type: '@'
                },
                controller: 'UibTabsetController',
                templateUrl: 'uib/template/tabs/tabset.html',
                link: function(scope, element, attrs) {
                    scope.vertical = angular.isDefined(attrs.vertical) ? scope.$parent.$eval(attrs.vertical) : false;
                    scope.justified = angular.isDefined(attrs.justified) ? scope.$parent.$eval(attrs.justified) : false;
                }
            };
        })
        .directive('uibTab', ['$parse', function($parse) {
            return {
                require: '^uibTabset',
                replace: true,
                templateUrl: 'uib/template/tabs/tab.html',
                transclude: true,
                scope: {
                    active: '=?',
                    heading: '@',
                    onSelect: '&select',
                    onDeselect: '&deselect'
                },
                controller: function() {},
                controllerAs: 'tab',
                link: function(scope, elm, attrs, tabsetCtrl, transclude) {
                    scope.$watch('active', function(active) {
                        if (active) {
                            tabsetCtrl.select(scope);
                        }
                    });
                    scope.disabled = false;
                    if (attrs.disable) {
                        scope.$parent.$watch($parse(attrs.disable), function(value) {
                            scope.disabled = !!value;
                        });
                    }
                    scope.select = function() {
                        if (!scope.disabled) {
                            scope.active = true;
                        }
                    };
                    tabsetCtrl.addTab(scope);
                    scope.$on('$destroy', function() {
                        tabsetCtrl.removeTab(scope);
                    });
                    scope.$transcludeFn = transclude;
                }
            };
        }])
        .directive('uibTabHeadingTransclude', function() {
            return {
                restrict: 'A',
                require: '^uibTab',
                link: function(scope, elm) {
                    scope.$watch('headingElement', function updateHeadingElement(heading) {
                        if (heading) {
                            elm.html('');
                            elm.append(heading);
                        }
                    });
                }
            };
        })
        .directive('uibTabContentTransclude', function() {
            return {
                restrict: 'A',
                require: '^uibTabset',
                link: function(scope, elm, attrs) {
                    var tab = scope.$eval(attrs.uibTabContentTransclude);
                    tab.$transcludeFn(tab.$parent, function(contents) {
                        angular.forEach(contents, function(node) {
                            if (isTabHeading(node)) {
                                tab.headingElement = node;
                            } else {
                                elm.append(node);
                            }
                        });
                    });
                }
            };
    
            function isTabHeading(node) {
                return node.tagName && (
                    node.hasAttribute('uib-tab-heading') ||
                    node.hasAttribute('data-uib-tab-heading') ||
                    node.hasAttribute('x-uib-tab-heading') ||
                    node.tagName.toLowerCase() === 'uib-tab-heading' ||
                    node.tagName.toLowerCase() === 'data-uib-tab-heading' ||
                    node.tagName.toLowerCase() === 'x-uib-tab-heading'
                );
            }
        });
    angular.module('ui.bootstrap.timepicker', [])
        .constant('uibTimepickerConfig', {
            hourStep: 1,
            minuteStep: 1,
            secondStep: 1,
            showMeridian: true,
            showSeconds: false,
            meridians: null,
            readonlyInput: false,
            mousewheel: true,
            arrowkeys: true,
            showSpinners: true,
            templateUrl: 'uib/template/timepicker/timepicker.html'
        })
        .controller('UibTimepickerController', ['$scope', '$element', '$attrs', '$parse', '$log', '$locale', 'uibTimepickerConfig', function($scope, $element, $attrs, $parse, $log, $locale, timepickerConfig) {
            var selected = new Date(),
                watchers = [],
                ngModelCtrl = {
                    $setViewValue: angular.noop
                },
                meridians = angular.isDefined($attrs.meridians) ? $scope.$parent.$eval($attrs.meridians) : timepickerConfig.meridians || $locale.DATETIME_FORMATS.AMPMS;
            $scope.tabindex = angular.isDefined($attrs.tabindex) ? $attrs.tabindex : 0;
            $element.removeAttr('tabindex');
            this.init = function(ngModelCtrl_, inputs) {
                ngModelCtrl = ngModelCtrl_;
                ngModelCtrl.$render = this.render;
                ngModelCtrl.$formatters.unshift(function(modelValue) {
                    return modelValue ? new Date(modelValue) : null;
                });
                var hoursInputEl = inputs.eq(0),
                    minutesInputEl = inputs.eq(1),
                    secondsInputEl = inputs.eq(2);
                var mousewheel = angular.isDefined($attrs.mousewheel) ? $scope.$parent.$eval($attrs.mousewheel) : timepickerConfig.mousewheel;
                if (mousewheel) {
                    this.setupMousewheelEvents(hoursInputEl, minutesInputEl, secondsInputEl);
                }
                var arrowkeys = angular.isDefined($attrs.arrowkeys) ? $scope.$parent.$eval($attrs.arrowkeys) : timepickerConfig.arrowkeys;
                if (arrowkeys) {
                    this.setupArrowkeyEvents(hoursInputEl, minutesInputEl, secondsInputEl);
                }
                $scope.readonlyInput = angular.isDefined($attrs.readonlyInput) ? $scope.$parent.$eval($attrs.readonlyInput) : timepickerConfig.readonlyInput;
                this.setupInputEvents(hoursInputEl, minutesInputEl, secondsInputEl);
            };
            var hourStep = timepickerConfig.hourStep;
            if ($attrs.hourStep) {
                watchers.push($scope.$parent.$watch($parse($attrs.hourStep), function(value) {
                    hourStep = +value;
                }));
            }
            var minuteStep = timepickerConfig.minuteStep;
            if ($attrs.minuteStep) {
                watchers.push($scope.$parent.$watch($parse($attrs.minuteStep), function(value) {
                    minuteStep = +value;
                }));
            }
            var min;
            watchers.push($scope.$parent.$watch($parse($attrs.min), function(value) {
                var dt = new Date(value);
                min = isNaN(dt) ? undefined : dt;
            }));
            var max;
            watchers.push($scope.$parent.$watch($parse($attrs.max), function(value) {
                var dt = new Date(value);
                max = isNaN(dt) ? undefined : dt;
            }));
            var disabled = false;
            if ($attrs.ngDisabled) {
                watchers.push($scope.$parent.$watch($parse($attrs.ngDisabled), function(value) {
                    disabled = value;
                }));
            }
            $scope.noIncrementHours = function() {
                var incrementedSelected = addMinutes(selected, hourStep * 60);
                return disabled || incrementedSelected > max ||
                    incrementedSelected < selected && incrementedSelected < min;
            };
            $scope.noDecrementHours = function() {
                var decrementedSelected = addMinutes(selected, -hourStep * 60);
                return disabled || decrementedSelected < min ||
                    decrementedSelected > selected && decrementedSelected > max;
            };
            $scope.noIncrementMinutes = function() {
                var incrementedSelected = addMinutes(selected, minuteStep);
                return disabled || incrementedSelected > max ||
                    incrementedSelected < selected && incrementedSelected < min;
            };
            $scope.noDecrementMinutes = function() {
                var decrementedSelected = addMinutes(selected, -minuteStep);
                return disabled || decrementedSelected < min ||
                    decrementedSelected > selected && decrementedSelected > max;
            };
            $scope.noIncrementSeconds = function() {
                var incrementedSelected = addSeconds(selected, secondStep);
                return disabled || incrementedSelected > max ||
                    incrementedSelected < selected && incrementedSelected < min;
            };
            $scope.noDecrementSeconds = function() {
                var decrementedSelected = addSeconds(selected, -secondStep);
                return disabled || decrementedSelected < min ||
                    decrementedSelected > selected && decrementedSelected > max;
            };
            $scope.noToggleMeridian = function() {
                if (selected.getHours() < 12) {
                    return disabled || addMinutes(selected, 12 * 60) > max;
                }
                return disabled || addMinutes(selected, -12 * 60) < min;
            };
            var secondStep = timepickerConfig.secondStep;
            if ($attrs.secondStep) {
                watchers.push($scope.$parent.$watch($parse($attrs.secondStep), function(value) {
                    secondStep = +value;
                }));
            }
            $scope.showSeconds = timepickerConfig.showSeconds;
            if ($attrs.showSeconds) {
                watchers.push($scope.$parent.$watch($parse($attrs.showSeconds), function(value) {
                    $scope.showSeconds = !!value;
                }));
            }
            $scope.showMeridian = timepickerConfig.showMeridian;
            if ($attrs.showMeridian) {
                watchers.push($scope.$parent.$watch($parse($attrs.showMeridian), function(value) {
                    $scope.showMeridian = !!value;
                    if (ngModelCtrl.$error.time) {
                        var hours = getHoursFromTemplate(),
                            minutes = getMinutesFromTemplate();
                        if (angular.isDefined(hours) && angular.isDefined(minutes)) {
                            selected.setHours(hours);
                            refresh();
                        }
                    } else {
                        updateTemplate();
                    }
                }));
            }
    
            function getHoursFromTemplate() {
                var hours = +$scope.hours;
                var valid = $scope.showMeridian ? hours > 0 && hours < 13 :
                    hours >= 0 && hours < 24;
                if (!valid) {
                    return undefined;
                }
                if ($scope.showMeridian) {
                    if (hours === 12) {
                        hours = 0;
                    }
                    if ($scope.meridian === meridians[1]) {
                        hours = hours + 12;
                    }
                }
                return hours;
            }
    
            function getMinutesFromTemplate() {
                var minutes = +$scope.minutes;
                return minutes >= 0 && minutes < 60 ? minutes : undefined;
            }
    
            function getSecondsFromTemplate() {
                var seconds = +$scope.seconds;
                return seconds >= 0 && seconds < 60 ? seconds : undefined;
            }
    
            function pad(value) {
                if (value === null) {
                    return '';
                }
                return angular.isDefined(value) && value.toString().length < 2 ?
                    '0' + value : value.toString();
            }
            this.setupMousewheelEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) {
                var isScrollingUp = function(e) {
                    if (e.originalEvent) {
                        e = e.originalEvent;
                    }
                    var delta = e.wheelDelta ? e.wheelDelta : -e.deltaY;
                    return e.detail || delta > 0;
                };
                hoursInputEl.bind('mousewheel wheel', function(e) {
                    if (!disabled) {
                        $scope.$apply(isScrollingUp(e) ? $scope.incrementHours() : $scope.decrementHours());
                    }
                    e.preventDefault();
                });
                minutesInputEl.bind('mousewheel wheel', function(e) {
                    if (!disabled) {
                        $scope.$apply(isScrollingUp(e) ? $scope.incrementMinutes() : $scope.decrementMinutes());
                    }
                    e.preventDefault();
                });
                secondsInputEl.bind('mousewheel wheel', function(e) {
                    if (!disabled) {
                        $scope.$apply(isScrollingUp(e) ? $scope.incrementSeconds() : $scope.decrementSeconds());
                    }
                    e.preventDefault();
                });
            };
            this.setupArrowkeyEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) {
                hoursInputEl.bind('keydown', function(e) {
                    if (!disabled) {
                        if (e.which === 38) {
                            e.preventDefault();
                            $scope.incrementHours();
                            $scope.$apply();
                        } else if (e.which === 40) {
                            e.preventDefault();
                            $scope.decrementHours();
                            $scope.$apply();
                        }
                    }
                });
                minutesInputEl.bind('keydown', function(e) {
                    if (!disabled) {
                        if (e.which === 38) {
                            e.preventDefault();
                            $scope.incrementMinutes();
                            $scope.$apply();
                        } else if (e.which === 40) {
                            e.preventDefault();
                            $scope.decrementMinutes();
                            $scope.$apply();
                        }
                    }
                });
                secondsInputEl.bind('keydown', function(e) {
                    if (!disabled) {
                        if (e.which === 38) {
                            e.preventDefault();
                            $scope.incrementSeconds();
                            $scope.$apply();
                        } else if (e.which === 40) {
                            e.preventDefault();
                            $scope.decrementSeconds();
                            $scope.$apply();
                        }
                    }
                });
            };
            this.setupInputEvents = function(hoursInputEl, minutesInputEl, secondsInputEl) {
                if ($scope.readonlyInput) {
                    $scope.updateHours = angular.noop;
                    $scope.updateMinutes = angular.noop;
                    $scope.updateSeconds = angular.noop;
                    return;
                }
                var invalidate = function(invalidHours, invalidMinutes, invalidSeconds) {
                    ngModelCtrl.$setViewValue(null);
                    ngModelCtrl.$setValidity('time', false);
                    if (angular.isDefined(invalidHours)) {
                        $scope.invalidHours = invalidHours;
                    }
                    if (angular.isDefined(invalidMinutes)) {
                        $scope.invalidMinutes = invalidMinutes;
                    }
                    if (angular.isDefined(invalidSeconds)) {
                        $scope.invalidSeconds = invalidSeconds;
                    }
                };
                $scope.updateHours = function() {
                    var hours = getHoursFromTemplate(),
                        minutes = getMinutesFromTemplate();
                    ngModelCtrl.$setDirty();
                    if (angular.isDefined(hours) && angular.isDefined(minutes)) {
                        selected.setHours(hours);
                        selected.setMinutes(minutes);
                        if (selected < min || selected > max) {
                            invalidate(true);
                        } else {
                            refresh('h');
                        }
                    } else {
                        invalidate(true);
                    }
                };
                hoursInputEl.bind('blur', function(e) {
                    ngModelCtrl.$setTouched();
                    if ($scope.hours === null || $scope.hours === '') {
                        invalidate(true);
                    } else if (!$scope.invalidHours && $scope.hours < 10) {
                        $scope.$apply(function() {
                            $scope.hours = pad($scope.hours);
                        });
                    }
                });
                $scope.updateMinutes = function() {
                    var minutes = getMinutesFromTemplate(),
                        hours = getHoursFromTemplate();
                    ngModelCtrl.$setDirty();
                    if (angular.isDefined(minutes) && angular.isDefined(hours)) {
                        selected.setHours(hours);
                        selected.setMinutes(minutes);
                        if (selected < min || selected > max) {
                            invalidate(undefined, true);
                        } else {
                            refresh('m');
                        }
                    } else {
                        invalidate(undefined, true);
                    }
                };
                minutesInputEl.bind('blur', function(e) {
                    ngModelCtrl.$setTouched();
                    if ($scope.minutes === null) {
                        invalidate(undefined, true);
                    } else if (!$scope.invalidMinutes && $scope.minutes < 10) {
                        $scope.$apply(function() {
                            $scope.minutes = pad($scope.minutes);
                        });
                    }
                });
                $scope.updateSeconds = function() {
                    var seconds = getSecondsFromTemplate();
                    ngModelCtrl.$setDirty();
                    if (angular.isDefined(seconds)) {
                        selected.setSeconds(seconds);
                        refresh('s');
                    } else {
                        invalidate(undefined, undefined, true);
                    }
                };
                secondsInputEl.bind('blur', function(e) {
                    if (!$scope.invalidSeconds && $scope.seconds < 10) {
                        $scope.$apply(function() {
                            $scope.seconds = pad($scope.seconds);
                        });
                    }
                });
            };
            this.render = function() {
                var date = ngModelCtrl.$viewValue;
                if (isNaN(date)) {
                    ngModelCtrl.$setValidity('time', false);
                    $log.error('Timepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.');
                } else {
                    if (date) {
                        selected = date;
                    }
                    if (selected < min || selected > max) {
                        ngModelCtrl.$setValidity('time', false);
                        $scope.invalidHours = true;
                        $scope.invalidMinutes = true;
                    } else {
                        makeValid();
                    }
                    updateTemplate();
                }
            };
    
            function refresh(keyboardChange) {
                makeValid();
                ngModelCtrl.$setViewValue(new Date(selected));
                updateTemplate(keyboardChange);
            }
    
            function makeValid() {
                ngModelCtrl.$setValidity('time', true);
                $scope.invalidHours = false;
                $scope.invalidMinutes = false;
                $scope.invalidSeconds = false;
            }
    
            function updateTemplate(keyboardChange) {
                if (!ngModelCtrl.$modelValue) {
                    $scope.hours = null;
                    $scope.minutes = null;
                    $scope.seconds = null;
                    $scope.meridian = meridians[0];
                } else {
                    var hours = selected.getHours(),
                        minutes = selected.getMinutes(),
                        seconds = selected.getSeconds();
                    if ($scope.showMeridian) {
                        hours = hours === 0 || hours === 12 ? 12 : hours % 12;
                    }
                    $scope.hours = keyboardChange === 'h' ? hours : pad(hours);
                    if (keyboardChange !== 'm') {
                        $scope.minutes = pad(minutes);
                    }
                    $scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1];
                    if (keyboardChange !== 's') {
                        $scope.seconds = pad(seconds);
                    }
                    $scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1];
                }
            }
    
            function addSecondsToSelected(seconds) {
                selected = addSeconds(selected, seconds);
                refresh();
            }
    
            function addMinutes(selected, minutes) {
                return addSeconds(selected, minutes * 60);
            }
    
            function addSeconds(date, seconds) {
                var dt = new Date(date.getTime() + seconds * 1000);
                var newDate = new Date(date);
                newDate.setHours(dt.getHours(), dt.getMinutes(), dt.getSeconds());
                return newDate;
            }
            $scope.showSpinners = angular.isDefined($attrs.showSpinners) ?
                $scope.$parent.$eval($attrs.showSpinners) : timepickerConfig.showSpinners;
            $scope.incrementHours = function() {
                if (!$scope.noIncrementHours()) {
                    addSecondsToSelected(hourStep * 60 * 60);
                }
            };
            $scope.decrementHours = function() {
                if (!$scope.noDecrementHours()) {
                    addSecondsToSelected(-hourStep * 60 * 60);
                }
            };
            $scope.incrementMinutes = function() {
                if (!$scope.noIncrementMinutes()) {
                    addSecondsToSelected(minuteStep * 60);
                }
            };
            $scope.decrementMinutes = function() {
                if (!$scope.noDecrementMinutes()) {
                    addSecondsToSelected(-minuteStep * 60);
                }
            };
            $scope.incrementSeconds = function() {
                if (!$scope.noIncrementSeconds()) {
                    addSecondsToSelected(secondStep);
                }
            };
            $scope.decrementSeconds = function() {
                if (!$scope.noDecrementSeconds()) {
                    addSecondsToSelected(-secondStep);
                }
            };
            $scope.toggleMeridian = function() {
                var minutes = getMinutesFromTemplate(),
                    hours = getHoursFromTemplate();
                if (!$scope.noToggleMeridian()) {
                    if (angular.isDefined(minutes) && angular.isDefined(hours)) {
                        addSecondsToSelected(12 * 60 * (selected.getHours() < 12 ? 60 : -60));
                    } else {
                        $scope.meridian = $scope.meridian === meridians[0] ? meridians[1] : meridians[0];
                    }
                }
            };
            $scope.blur = function() {
                ngModelCtrl.$setTouched();
            };
            $scope.$on('$destroy', function() {
                while (watchers.length) {
                    watchers.shift()();
                }
            });
        }])
        .directive('uibTimepicker', ['uibTimepickerConfig', function(uibTimepickerConfig) {
            return {
                require: ['uibTimepicker', '?^ngModel'],
                controller: 'UibTimepickerController',
                controllerAs: 'timepicker',
                replace: true,
                scope: {},
                templateUrl: function(element, attrs) {
                    return attrs.templateUrl || uibTimepickerConfig.templateUrl;
                },
                link: function(scope, element, attrs, ctrls) {
                    var timepickerCtrl = ctrls[0],
                        ngModelCtrl = ctrls[1];
                    if (ngModelCtrl) {
                        timepickerCtrl.init(ngModelCtrl, element.find('input'));
                    }
                }
            };
        }]);
    angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.debounce', 'ui.bootstrap.position'])
        .factory('uibTypeaheadParser', ['$parse', function($parse) {
            var TYPEAHEAD_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+([\s\S]+?)$/;
            return {
                parse: function(input) {
                    var match = input.match(TYPEAHEAD_REGEXP);
                    if (!match) {
                        throw new Error(
                            'Expected typeahead specification in form of "_modelValue_ (as _label_)? for _item_ in _collection_"' +
                            ' but got "' + input + '".');
                    }
                    return {
                        itemName: match[3],
                        source: $parse(match[4]),
                        viewMapper: $parse(match[2] || match[1]),
                        modelMapper: $parse(match[1])
                    };
                }
            };
        }])
        .controller('UibTypeaheadController', ['$scope', '$element', '$attrs', '$compile', '$parse', '$q', '$timeout', '$document', '$window', '$rootScope', '$$debounce', '$uibPosition', 'uibTypeaheadParser',
            function(originalScope, element, attrs, $compile, $parse, $q, $timeout, $document, $window, $rootScope, $$debounce, $position, typeaheadParser) {
                var HOT_KEYS = [9, 13, 27, 38, 40];
                var eventDebounceTime = 200;
                var modelCtrl, ngModelOptions;
                var minLength = originalScope.$eval(attrs.typeaheadMinLength);
                if (!minLength && minLength !== 0) {
                    minLength = 1;
                }
                var waitTime = originalScope.$eval(attrs.typeaheadWaitMs) || 0;
                var isEditable = originalScope.$eval(attrs.typeaheadEditable) !== false;
                originalScope.$watch(attrs.typeaheadEditable, function(newVal) {
                    isEditable = newVal !== false;
                });
                var isLoadingSetter = $parse(attrs.typeaheadLoading).assign || angular.noop;
                var onSelectCallback = $parse(attrs.typeaheadOnSelect);
                var isSelectOnBlur = angular.isDefined(attrs.typeaheadSelectOnBlur) ? originalScope.$eval(attrs.typeaheadSelectOnBlur) : false;
                var isNoResultsSetter = $parse(attrs.typeaheadNoResults).assign || angular.noop;
                var inputFormatter = attrs.typeaheadInputFormatter ? $parse(attrs.typeaheadInputFormatter) : undefined;
                var appendToBody = attrs.typeaheadAppendToBody ? originalScope.$eval(attrs.typeaheadAppendToBody) : false;
                var appendTo = attrs.typeaheadAppendTo ?
                    originalScope.$eval(attrs.typeaheadAppendTo) : null;
                var focusFirst = originalScope.$eval(attrs.typeaheadFocusFirst) !== false;
                var selectOnExact = attrs.typeaheadSelectOnExact ? originalScope.$eval(attrs.typeaheadSelectOnExact) : false;
                var isOpenSetter = $parse(attrs.typeaheadIsOpen).assign || angular.noop;
                var showHint = originalScope.$eval(attrs.typeaheadShowHint) || false;
                var parsedModel = $parse(attrs.ngModel);
                var invokeModelSetter = $parse(attrs.ngModel + '($$$p)');
                var $setModelValue = function(scope, newValue) {
                    if (angular.isFunction(parsedModel(originalScope)) &&
                        ngModelOptions && ngModelOptions.$options && ngModelOptions.$options.getterSetter) {
                        return invokeModelSetter(scope, {
                            $$$p: newValue
                        });
                    }
                    return parsedModel.assign(scope, newValue);
                };
                var parserResult = typeaheadParser.parse(attrs.uibTypeahead);
                var hasFocus;
                var selected;
                var scope = originalScope.$new();
                var offDestroy = originalScope.$on('$destroy', function() {
                    scope.$destroy();
                });
                scope.$on('$destroy', offDestroy);
                var popupId = 'typeahead-' + scope.$id + '-' + Math.floor(Math.random() * 10000);
                element.attr({
                    'aria-autocomplete': 'list',
                    'aria-expanded': false,
                    'aria-owns': popupId
                });
                var inputsContainer, hintInputElem;
                if (showHint) {
                    inputsContainer = angular.element('<div></div>');
                    inputsContainer.css('position', 'relative');
                    element.after(inputsContainer);
                    hintInputElem = element.clone();
                    hintInputElem.attr('placeholder', '');
                    hintInputElem.val('');
                    hintInputElem.css({
                        'position': 'absolute',
                        'top': '0px',
                        'left': '0px',
                        'border-color': 'transparent',
                        'box-shadow': 'none',
                        'opacity': 1,
                        'background': 'none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255)',
                        'color': '#999'
                    });
                    element.css({
                        'position': 'relative',
                        'vertical-align': 'top',
                        'background-color': 'transparent'
                    });
                    inputsContainer.append(hintInputElem);
                    hintInputElem.after(element);
                }
                var popUpEl = angular.element('<div uib-typeahead-popup></div>');
                popUpEl.attr({
                    id: popupId,
                    matches: 'matches',
                    active: 'activeIdx',
                    select: 'select(activeIdx, evt)',
                    'move-in-progress': 'moveInProgress',
                    query: 'query',
                    position: 'position',
                    'assign-is-open': 'assignIsOpen(isOpen)',
                    debounce: 'debounceUpdate'
                });
                if (angular.isDefined(attrs.typeaheadTemplateUrl)) {
                    popUpEl.attr('template-url', attrs.typeaheadTemplateUrl);
                }
                if (angular.isDefined(attrs.typeaheadPopupTemplateUrl)) {
                    popUpEl.attr('popup-template-url', attrs.typeaheadPopupTemplateUrl);
                }
                var resetHint = function() {
                    if (showHint) {
                        hintInputElem.val('');
                    }
                };
                var resetMatches = function() {
                    scope.matches = [];
                    scope.activeIdx = -1;
                    element.attr('aria-expanded', false);
                    resetHint();
                };
                var getMatchId = function(index) {
                    return popupId + '-option-' + index;
                };
                scope.$watch('activeIdx', function(index) {
                    if (index < 0) {
                        element.removeAttr('aria-activedescendant');
                    } else {
                        element.attr('aria-activedescendant', getMatchId(index));
                    }
                });
                var inputIsExactMatch = function(inputValue, index) {
                    if (scope.matches.length > index && inputValue) {
                        return inputValue.toUpperCase() === scope.matches[index].label.toUpperCase();
                    }
                    return false;
                };
                var getMatchesAsync = function(inputValue, evt) {
                    var locals = {
                        $viewValue: inputValue
                    };
                    isLoadingSetter(originalScope, true);
                    isNoResultsSetter(originalScope, false);
                    $q.when(parserResult.source(originalScope, locals)).then(function(matches) {
                        var onCurrentRequest = inputValue === modelCtrl.$viewValue;
                        if (onCurrentRequest && hasFocus) {
                            if (matches && matches.length > 0) {
                                scope.activeIdx = focusFirst ? 0 : -1;
                                isNoResultsSetter(originalScope, false);
                                scope.matches.length = 0;
                                for (var i = 0; i < matches.length; i++) {
                                    locals[parserResult.itemName] = matches[i];
                                    scope.matches.push({
                                        id: getMatchId(i),
                                        label: parserResult.viewMapper(scope, locals),
                                        model: matches[i]
                                    });
                                }
                                scope.query = inputValue;
                                recalculatePosition();
                                element.attr('aria-expanded', true);
                                if (selectOnExact && scope.matches.length === 1 && inputIsExactMatch(inputValue, 0)) {
                                    if (angular.isNumber(scope.debounceUpdate) || angular.isObject(scope.debounceUpdate)) {
                                        $$debounce(function() {
                                            scope.select(0, evt);
                                        }, angular.isNumber(scope.debounceUpdate) ? scope.debounceUpdate : scope.debounceUpdate['default']);
                                    } else {
                                        scope.select(0, evt);
                                    }
                                }
                                if (showHint) {
                                    var firstLabel = scope.matches[0].label;
                                    if (angular.isString(inputValue) &&
                                        inputValue.length > 0 &&
                                        firstLabel.slice(0, inputValue.length).toUpperCase() === inputValue.toUpperCase()) {
                                        hintInputElem.val(inputValue + firstLabel.slice(inputValue.length));
                                    } else {
                                        hintInputElem.val('');
                                    }
                                }
                            } else {
                                resetMatches();
                                isNoResultsSetter(originalScope, true);
                            }
                        }
                        if (onCurrentRequest) {
                            isLoadingSetter(originalScope, false);
                        }
                    }, function() {
                        resetMatches();
                        isLoadingSetter(originalScope, false);
                        isNoResultsSetter(originalScope, true);
                    });
                };
                if (appendToBody) {
                    angular.element($window).on('resize', fireRecalculating);
                    $document.find('body').on('scroll', fireRecalculating);
                }
                var debouncedRecalculate = $$debounce(function() {
                    if (scope.matches.length) {
                        recalculatePosition();
                    }
                    scope.moveInProgress = false;
                }, eventDebounceTime);
                scope.moveInProgress = false;
    
                function fireRecalculating() {
                    if (!scope.moveInProgress) {
                        scope.moveInProgress = true;
                        scope.$digest();
                    }
                    debouncedRecalculate();
                }
    
                function recalculatePosition() {
                    scope.position = appendToBody ? $position.offset(element) : $position.position(element);
                    scope.position.top += element.prop('offsetHeight');
                }
                scope.query = undefined;
                var timeoutPromise;
                var scheduleSearchWithTimeout = function(inputValue) {
                    timeoutPromise = $timeout(function() {
                        getMatchesAsync(inputValue);
                    }, waitTime);
                };
                var cancelPreviousTimeout = function() {
                    if (timeoutPromise) {
                        $timeout.cancel(timeoutPromise);
                    }
                };
                resetMatches();
                scope.assignIsOpen = function(isOpen) {
                    isOpenSetter(originalScope, isOpen);
                };
                scope.select = function(activeIdx, evt) {
                    var locals = {};
                    var model, item;
                    selected = true;
                    locals[parserResult.itemName] = item = scope.matches[activeIdx].model;
                    model = parserResult.modelMapper(originalScope, locals);
                    $setModelValue(originalScope, model);
                    modelCtrl.$setValidity('editable', true);
                    modelCtrl.$setValidity('parse', true);
                    onSelectCallback(originalScope, {
                        $item: item,
                        $model: model,
                        $label: parserResult.viewMapper(originalScope, locals),
                        $event: evt
                    });
                    resetMatches();
                    if (scope.$eval(attrs.typeaheadFocusOnSelect) !== false) {
                        $timeout(function() {
                            element[0].focus();
                        }, 0, false);
                    }
                };
                element.on('keydown', function(evt) {
                    if (scope.matches.length === 0 || HOT_KEYS.indexOf(evt.which) === -1) {
                        return;
                    }
                    if (scope.activeIdx === -1 && (evt.which === 9 || evt.which === 13)) {
                        resetMatches();
                        scope.$digest();
                        return;
                    }
                    evt.preventDefault();
                    var target;
                    switch (evt.which) {
                        case 9:
                        case 13:
                            scope.$apply(function() {
                                if (angular.isNumber(scope.debounceUpdate) || angular.isObject(scope.debounceUpdate)) {
                                    $$debounce(function() {
                                        scope.select(scope.activeIdx, evt);
                                    }, angular.isNumber(scope.debounceUpdate) ? scope.debounceUpdate : scope.debounceUpdate['default']);
                                } else {
                                    scope.select(scope.activeIdx, evt);
                                }
                            });
                            break;
                        case 27:
                            evt.stopPropagation();
                            resetMatches();
                            scope.$digest();
                            break;
                        case 38:
                            scope.activeIdx = (scope.activeIdx > 0 ? scope.activeIdx : scope.matches.length) - 1;
                            scope.$digest();
                            target = popUpEl.find('li')[scope.activeIdx];
                            target.parentNode.scrollTop = target.offsetTop;
                            break;
                        case 40:
                            scope.activeIdx = (scope.activeIdx + 1) % scope.matches.length;
                            scope.$digest();
                            target = popUpEl.find('li')[scope.activeIdx];
                            target.parentNode.scrollTop = target.offsetTop;
                            break;
                    }
                });
                element.bind('focus', function(evt) {
                    hasFocus = true;
                    if (minLength === 0 && !modelCtrl.$viewValue) {
                        $timeout(function() {
                            getMatchesAsync(modelCtrl.$viewValue, evt);
                        }, 0);
                    }
                });
                element.bind('blur', function(evt) {
                    if (isSelectOnBlur && scope.matches.length && scope.activeIdx !== -1 && !selected) {
                        selected = true;
                        scope.$apply(function() {
                            if (angular.isObject(scope.debounceUpdate) && angular.isNumber(scope.debounceUpdate.blur)) {
                                $$debounce(function() {
                                    scope.select(scope.activeIdx, evt);
                                }, scope.debounceUpdate.blur);
                            } else {
                                scope.select(scope.activeIdx, evt);
                            }
                        });
                    }
                    if (!isEditable && modelCtrl.$error.editable) {
                        modelCtrl.$viewValue = '';
                        element.val('');
                    }
                    hasFocus = false;
                    selected = false;
                });
                var dismissClickHandler = function(evt) {
                    if (element[0] !== evt.target && evt.which !== 3 && scope.matches.length !== 0) {
                        resetMatches();
                        if (!$rootScope.$$phase) {
                            scope.$digest();
                        }
                    }
                };
                $document.on('click', dismissClickHandler);
                originalScope.$on('$destroy', function() {
                    $document.off('click', dismissClickHandler);
                    if (appendToBody || appendTo) {
                        $popup.remove();
                    }
                    if (appendToBody) {
                        angular.element($window).off('resize', fireRecalculating);
                        $document.find('body').off('scroll', fireRecalculating);
                    }
                    popUpEl.remove();
                    if (showHint) {
                        inputsContainer.remove();
                    }
                });
                var $popup = $compile(popUpEl)(scope);
                if (appendToBody) {
                    $document.find('body').append($popup);
                } else if (appendTo) {
                    angular.element(appendTo).eq(0).append($popup);
                } else {
                    element.after($popup);
                }
                this.init = function(_modelCtrl, _ngModelOptions) {
                    modelCtrl = _modelCtrl;
                    ngModelOptions = _ngModelOptions;
                    scope.debounceUpdate = modelCtrl.$options && $parse(modelCtrl.$options.debounce)(originalScope);
                    modelCtrl.$parsers.unshift(function(inputValue) {
                        hasFocus = true;
                        if (minLength === 0 || inputValue && inputValue.length >= minLength) {
                            if (waitTime > 0) {
                                cancelPreviousTimeout();
                                scheduleSearchWithTimeout(inputValue);
                            } else {
                                getMatchesAsync(inputValue);
                            }
                        } else {
                            isLoadingSetter(originalScope, false);
                            cancelPreviousTimeout();
                            resetMatches();
                        }
                        if (isEditable) {
                            return inputValue;
                        }
                        if (!inputValue) {
                            modelCtrl.$setValidity('editable', true);
                            return null;
                        }
                        modelCtrl.$setValidity('editable', false);
                        return undefined;
                    });
                    modelCtrl.$formatters.push(function(modelValue) {
                        var candidateViewValue, emptyViewValue;
                        var locals = {};
                        if (!isEditable) {
                            modelCtrl.$setValidity('editable', true);
                        }
                        if (inputFormatter) {
                            locals.$model = modelValue;
                            return inputFormatter(originalScope, locals);
                        }
                        locals[parserResult.itemName] = modelValue;
                        candidateViewValue = parserResult.viewMapper(originalScope, locals);
                        locals[parserResult.itemName] = undefined;
                        emptyViewValue = parserResult.viewMapper(originalScope, locals);
                        return candidateViewValue !== emptyViewValue ? candidateViewValue : modelValue;
                    });
                };
            }
        ])
        .directive('uibTypeahead', function() {
            return {
                controller: 'UibTypeaheadController',
                require: ['ngModel', '^?ngModelOptions', 'uibTypeahead'],
                link: function(originalScope, element, attrs, ctrls) {
                    ctrls[2].init(ctrls[0], ctrls[1]);
                }
            };
        })
        .directive('uibTypeaheadPopup', ['$$debounce', function($$debounce) {
            return {
                scope: {
                    matches: '=',
                    query: '=',
                    active: '=',
                    position: '&',
                    moveInProgress: '=',
                    select: '&',
                    assignIsOpen: '&',
                    debounce: '&'
                },
                replace: true,
                templateUrl: function(element, attrs) {
                    return attrs.popupTemplateUrl || 'uib/template/typeahead/typeahead-popup.html';
                },
                link: function(scope, element, attrs) {
                    scope.templateUrl = attrs.templateUrl;
                    scope.isOpen = function() {
                        var isDropdownOpen = scope.matches.length > 0;
                        scope.assignIsOpen({
                            isOpen: isDropdownOpen
                        });
                        return isDropdownOpen;
                    };
                    scope.isActive = function(matchIdx) {
                        return scope.active === matchIdx;
                    };
                    scope.selectActive = function(matchIdx) {
                        scope.active = matchIdx;
                    };
                    scope.selectMatch = function(activeIdx, evt) {
                        var debounce = scope.debounce();
                        if (angular.isNumber(debounce) || angular.isObject(debounce)) {
                            $$debounce(function() {
                                scope.select({
                                    activeIdx: activeIdx,
                                    evt: evt
                                });
                            }, angular.isNumber(debounce) ? debounce : debounce['default']);
                        } else {
                            scope.select({
                                activeIdx: activeIdx,
                                evt: evt
                            });
                        }
                    };
                }
            };
        }])
        .directive('uibTypeaheadMatch', ['$templateRequest', '$compile', '$parse', function($templateRequest, $compile, $parse) {
            return {
                scope: {
                    index: '=',
                    match: '=',
                    query: '='
                },
                link: function(scope, element, attrs) {
                    var tplUrl = $parse(attrs.templateUrl)(scope.$parent) || 'uib/template/typeahead/typeahead-match.html';
                    $templateRequest(tplUrl).then(function(tplContent) {
                        var tplEl = angular.element(tplContent.trim());
                        element.replaceWith(tplEl);
                        $compile(tplEl)(scope);
                    });
                }
            };
        }])
        .filter('uibTypeaheadHighlight', ['$sce', '$injector', '$log', function($sce, $injector, $log) {
            var isSanitizePresent;
            isSanitizePresent = $injector.has('$sanitize');
    
            function escapeRegexp(queryToEscape) {
                return queryToEscape.replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
            }
    
            function containsHtml(matchItem) {
                return /<.*>/g.test(matchItem);
            }
            return function(matchItem, query) {
                if (!isSanitizePresent && containsHtml(matchItem)) {
                    $log.warn('Unsafe use of typeahead please use ngSanitize');
                }
                matchItem = query ? ('' + matchItem).replace(new RegExp(escapeRegexp(query), 'gi'), '<strong>$&</strong>') : matchItem;
                if (!isSanitizePresent) {
                    matchItem = $sce.trustAsHtml(matchItem);
                }
                return matchItem;
            };
        }]);
    angular.module("uib/template/accordion/accordion-group.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/accordion/accordion-group.html",
            "<div class=\"panel\" ng-class=\"panelClass || 'panel-default'\">\n" +
            "  <div role=\"tab\" id=\"{{::headingId}}\" aria-selected=\"{{isOpen}}\" class=\"panel-heading\" ng-keypress=\"toggleOpen($event)\">\n" +
            "    <h4 class=\"panel-title\">\n" +
            "      <a role=\"button\" data-toggle=\"collapse\" href aria-expanded=\"{{isOpen}}\" aria-controls=\"{{::panelId}}\" tabindex=\"0\" class=\"accordion-toggle\" ng-click=\"toggleOpen()\" uib-accordion-transclude=\"heading\"><span ng-class=\"{'text-muted': isDisabled}\">{{heading}}</span></a>\n" +
            "    </h4>\n" +
            "  </div>\n" +
            "  <div id=\"{{::panelId}}\" aria-labelledby=\"{{::headingId}}\" aria-hidden=\"{{!isOpen}}\" role=\"tabpanel\" class=\"panel-collapse collapse\" uib-collapse=\"!isOpen\">\n" +
            "    <div class=\"panel-body\" ng-transclude></div>\n" +
            "  </div>\n" +
            "</div>\n" +
            "");
    }]);
    angular.module("uib/template/accordion/accordion.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/accordion/accordion.html",
            "<div role=\"tablist\" class=\"panel-group\" ng-transclude></div>");
    }]);
    angular.module("uib/template/alert/alert.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/alert/alert.html",
            "<div class=\"alert\" ng-class=\"['alert-' + (type || 'warning'), closeable ? 'alert-dismissible' : null]\" role=\"alert\">\n" +
            "    <button ng-show=\"closeable\" type=\"button\" class=\"close\" ng-click=\"close({$event: $event})\">\n" +
            "        <span aria-hidden=\"true\">&times;</span>\n" +
            "        <span class=\"sr-only\">Close</span>\n" +
            "    </button>\n" +
            "    <div ng-transclude></div>\n" +
            "</div>\n" +
            "");
    }]);
    angular.module("uib/template/carousel/carousel.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/carousel/carousel.html",
            "<div ng-mouseenter=\"pause()\" ng-mouseleave=\"play()\" class=\"carousel\" ng-swipe-right=\"prev()\" ng-swipe-left=\"next()\">\n" +
            "  <div class=\"carousel-inner\" ng-transclude></div>\n" +
            "  <a role=\"button\" href class=\"left carousel-control\" ng-click=\"prev()\" ng-show=\"slides.length > 1\">\n" +
            "    <span aria-hidden=\"true\" class=\"glyphicon glyphicon-chevron-left\"></span>\n" +
            "    <span class=\"sr-only\">previous</span>\n" +
            "  </a>\n" +
            "  <a role=\"button\" href class=\"right carousel-control\" ng-click=\"next()\" ng-show=\"slides.length > 1\">\n" +
            "    <span aria-hidden=\"true\" class=\"glyphicon glyphicon-chevron-right\"></span>\n" +
            "    <span class=\"sr-only\">next</span>\n" +
            "  </a>\n" +
            "  <ol class=\"carousel-indicators\" ng-show=\"slides.length > 1\">\n" +
            "    <li ng-repeat=\"slide in slides | orderBy:indexOfSlide track by $index\" ng-class=\"{ active: isActive(slide) }\" ng-click=\"select(slide)\">\n" +
            "      <span class=\"sr-only\">slide {{ $index + 1 }} of {{ slides.length }}<span ng-if=\"isActive(slide)\">, currently active</span></span>\n" +
            "    </li>\n" +
            "  </ol>\n" +
            "</div>");
    }]);
    angular.module("uib/template/carousel/slide.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/carousel/slide.html",
            "<div ng-class=\"{\n" +
            "    'active': active\n" +
            "  }\" class=\"item text-center\" ng-transclude></div>\n" +
            "");
    }]);
    angular.module("uib/template/datepicker/datepicker.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/datepicker/datepicker.html",
            "<div class=\"uib-datepicker\" ng-switch=\"datepickerMode\" role=\"application\" ng-keydown=\"keydown($event)\">\n" +
            "  <uib-daypicker ng-switch-when=\"day\" tabindex=\"0\"></uib-daypicker>\n" +
            "  <uib-monthpicker ng-switch-when=\"month\" tabindex=\"0\"></uib-monthpicker>\n" +
            "  <uib-yearpicker ng-switch-when=\"year\" tabindex=\"0\"></uib-yearpicker>\n" +
            "</div>");
    }]);
    angular.module("uib/template/datepicker/day.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/datepicker/day.html",
            "<table class=\"uib-daypicker\" role=\"grid\" aria-labelledby=\"{{::uniqueId}}-title\" aria-activedescendant=\"{{activeDateId}}\">\n" +
            "  <thead>\n" +
            "    <tr>\n" +
            "      <th><button type=\"button\" class=\"btn btn-default btn-sm pull-left uib-left\" ng-click=\"move(-1)\" tabindex=\"-1\"><i class=\"glyphicon glyphicon-chevron-left\"></i></button></th>\n" +
            "      <th colspan=\"{{::5 + showWeeks}}\"><button id=\"{{::uniqueId}}-title\" role=\"heading\" aria-live=\"assertive\" aria-atomic=\"true\" type=\"button\" class=\"btn btn-default btn-sm uib-title\" ng-click=\"toggleMode()\" ng-disabled=\"datepickerMode === maxMode\" tabindex=\"-1\"><strong>{{title}}</strong></button></th>\n" +
            "      <th><button type=\"button\" class=\"btn btn-default btn-sm pull-right uib-right\" ng-click=\"move(1)\" tabindex=\"-1\"><i class=\"glyphicon glyphicon-chevron-right\"></i></button></th>\n" +
            "    </tr>\n" +
            "    <tr>\n" +
            "      <th ng-if=\"showWeeks\" class=\"text-center\"></th>\n" +
            "      <th ng-repeat=\"label in ::labels track by $index\" class=\"text-center\"><small aria-label=\"{{::label.full}}\">{{::label.abbr}}</small></th>\n" +
            "    </tr>\n" +
            "  </thead>\n" +
            "  <tbody>\n" +
            "    <tr class=\"uib-weeks\" ng-repeat=\"row in rows track by $index\">\n" +
            "      <td ng-if=\"showWeeks\" class=\"text-center h6\"><em>{{ weekNumbers[$index] }}</em></td>\n" +
            "      <td ng-repeat=\"dt in row\" class=\"uib-day text-center\" role=\"gridcell\"\n" +
            "        id=\"{{::dt.uid}}\"\n" +
            "        ng-class=\"::dt.customClass\">\n" +
            "        <button type=\"button\" class=\"btn btn-default btn-sm\"\n" +
            "          uib-is-class=\"\n" +
            "            'btn-info' for selectedDt,\n" +
            "            'active' for activeDt\n" +
            "            on dt\"\n" +
            "          ng-click=\"select(dt.date)\"\n" +
            "          ng-disabled=\"::dt.disabled\"\n" +
            "          tabindex=\"-1\"><span ng-class=\"::{'text-muted': dt.secondary, 'text-info': dt.current}\">{{::dt.label}}</span></button>\n" +
            "      </td>\n" +
            "    </tr>\n" +
            "  </tbody>\n" +
            "</table>\n" +
            "");
    }]);
    angular.module("uib/template/datepicker/month.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/datepicker/month.html",
            "<table class=\"uib-monthpicker\" role=\"grid\" aria-labelledby=\"{{::uniqueId}}-title\" aria-activedescendant=\"{{activeDateId}}\">\n" +
            "  <thead>\n" +
            "    <tr>\n" +
            "      <th><button type=\"button\" class=\"btn btn-default btn-sm pull-left uib-left\" ng-click=\"move(-1)\" tabindex=\"-1\"><i class=\"glyphicon glyphicon-chevron-left\"></i></button></th>\n" +
            "      <th><button id=\"{{::uniqueId}}-title\" role=\"heading\" aria-live=\"assertive\" aria-atomic=\"true\" type=\"button\" class=\"btn btn-default btn-sm uib-title\" ng-click=\"toggleMode()\" ng-disabled=\"datepickerMode === maxMode\" tabindex=\"-1\"><strong>{{title}}</strong></button></th>\n" +
            "      <th><button type=\"button\" class=\"btn btn-default btn-sm pull-right uib-right\" ng-click=\"move(1)\" tabindex=\"-1\"><i class=\"glyphicon glyphicon-chevron-right\"></i></button></th>\n" +
            "    </tr>\n" +
            "  </thead>\n" +
            "  <tbody>\n" +
            "    <tr class=\"uib-months\" ng-repeat=\"row in rows track by $index\">\n" +
            "      <td ng-repeat=\"dt in row\" class=\"uib-month text-center\" role=\"gridcell\"\n" +
            "        id=\"{{::dt.uid}}\"\n" +
            "        ng-class=\"::dt.customClass\">\n" +
            "        <button type=\"button\" class=\"btn btn-default\"\n" +
            "          uib-is-class=\"\n" +
            "            'btn-info' for selectedDt,\n" +
            "            'active' for activeDt\n" +
            "            on dt\"\n" +
            "          ng-click=\"select(dt.date)\"\n" +
            "          ng-disabled=\"::dt.disabled\"\n" +
            "          tabindex=\"-1\"><span ng-class=\"::{'text-info': dt.current}\">{{::dt.label}}</span></button>\n" +
            "      </td>\n" +
            "    </tr>\n" +
            "  </tbody>\n" +
            "</table>\n" +
            "");
    }]);
    angular.module("uib/template/datepicker/popup.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/datepicker/popup.html",
            "<div>\n" +
            "  <ul class=\"uib-datepicker-popup dropdown-menu\" dropdown-nested ng-if=\"isOpen\" ng-style=\"{top: position.top+'px', left: position.left+'px'}\" ng-keydown=\"keydown($event)\" ng-click=\"$event.stopPropagation()\">\n" +
            "    <li ng-transclude></li>\n" +
            "    <li ng-if=\"showButtonBar\" class=\"uib-button-bar\">\n" +
            "    <span class=\"btn-group pull-left\">\n" +
            "      <button type=\"button\" class=\"btn btn-sm btn-info uib-datepicker-current\" ng-click=\"select('today')\" ng-disabled=\"isDisabled('today')\">{{ getText('current') }}</button>\n" +
            "      <button type=\"button\" class=\"btn btn-sm btn-danger uib-clear\" ng-click=\"select(null)\">{{ getText('clear') }}</button>\n" +
            "    </span>\n" +
            "      <button type=\"button\" class=\"btn btn-sm btn-success pull-right uib-close\" ng-click=\"close()\">{{ getText('close') }}</button>\n" +
            "    </li>\n" +
            "  </ul>\n" +
            "</div>\n" +
            "");
    }]);
    angular.module("uib/template/datepicker/year.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/datepicker/year.html",
            "<table class=\"uib-yearpicker\" role=\"grid\" aria-labelledby=\"{{::uniqueId}}-title\" aria-activedescendant=\"{{activeDateId}}\">\n" +
            "  <thead>\n" +
            "    <tr>\n" +
            "      <th><button type=\"button\" class=\"btn btn-default btn-sm pull-left uib-left\" ng-click=\"move(-1)\" tabindex=\"-1\"><i class=\"glyphicon glyphicon-chevron-left\"></i></button></th>\n" +
            "      <th colspan=\"{{::columns - 2}}\"><button id=\"{{::uniqueId}}-title\" role=\"heading\" aria-live=\"assertive\" aria-atomic=\"true\" type=\"button\" class=\"btn btn-default btn-sm uib-title\" ng-click=\"toggleMode()\" ng-disabled=\"datepickerMode === maxMode\" tabindex=\"-1\"><strong>{{title}}</strong></button></th>\n" +
            "      <th><button type=\"button\" class=\"btn btn-default btn-sm pull-right uib-right\" ng-click=\"move(1)\" tabindex=\"-1\"><i class=\"glyphicon glyphicon-chevron-right\"></i></button></th>\n" +
            "    </tr>\n" +
            "  </thead>\n" +
            "  <tbody>\n" +
            "    <tr class=\"uib-years\" ng-repeat=\"row in rows track by $index\">\n" +
            "      <td ng-repeat=\"dt in row\" class=\"uib-year text-center\" role=\"gridcell\"\n" +
            "        id=\"{{::dt.uid}}\"\n" +
            "        ng-class=\"::dt.customClass\">\n" +
            "        <button type=\"button\" class=\"btn btn-default\"\n" +
            "          uib-is-class=\"\n" +
            "            'btn-info' for selectedDt,\n" +
            "            'active' for activeDt\n" +
            "            on dt\"\n" +
            "          ng-click=\"select(dt.date)\"\n" +
            "          ng-disabled=\"::dt.disabled\"\n" +
            "          tabindex=\"-1\"><span ng-class=\"::{'text-info': dt.current}\">{{::dt.label}}</span></button>\n" +
            "      </td>\n" +
            "    </tr>\n" +
            "  </tbody>\n" +
            "</table>\n" +
            "");
    }]);
    angular.module("uib/template/modal/backdrop.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/modal/backdrop.html",
            "<div class=\"modal-backdrop\"\n" +
            "     uib-modal-animation-class=\"fade\"\n" +
            "     modal-in-class=\"in\"\n" +
            "     ng-style=\"{'z-index': 1040 + (index && 1 || 0) + index*10}\"\n" +
            "></div>\n" +
            "");
    }]);
    angular.module("uib/template/modal/window.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/modal/window.html",
            "<div modal-render=\"{{$isRendered}}\" tabindex=\"-1\" role=\"dialog\" class=\"modal\"\n" +
            "    uib-modal-animation-class=\"fade\"\n" +
            "    modal-in-class=\"in\"\n" +
            "    ng-style=\"{'z-index': 1050 + index*10, display: 'block'}\">\n" +
            "    <div class=\"modal-dialog {{size ? 'modal-' + size : ''}}\"><div class=\"modal-content\" uib-modal-transclude></div></div>\n" +
            "</div>\n" +
            "");
    }]);
    angular.module("uib/template/pager/pager.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/pager/pager.html",
            "<ul class=\"pager\">\n" +
            "  <li ng-class=\"{disabled: noPrevious()||ngDisabled, previous: align}\"><a href ng-click=\"selectPage(page - 1, $event)\">{{::getText('previous')}}</a></li>\n" +
            "  <li ng-class=\"{disabled: noNext()||ngDisabled, next: align}\"><a href ng-click=\"selectPage(page + 1, $event)\">{{::getText('next')}}</a></li>\n" +
            "</ul>\n" +
            "");
    }]);
    angular.module("uib/template/pagination/pagination.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/pagination/pagination.html",
            "<ul class=\"pagination\">\n" +
            "  <li ng-if=\"::boundaryLinks\" ng-class=\"{disabled: noPrevious()||ngDisabled}\" class=\"pagination-first\"><a href ng-click=\"selectPage(1, $event)\">{{::getText('first')}}</a></li>\n" +
            "  <li ng-if=\"::directionLinks\" ng-class=\"{disabled: noPrevious()||ngDisabled}\" class=\"pagination-prev\"><a href ng-click=\"selectPage(page - 1, $event)\">{{::getText('previous')}}</a></li>\n" +
            "  <li ng-repeat=\"page in pages track by $index\" ng-class=\"{active: page.active,disabled: ngDisabled&&!page.active}\" class=\"pagination-page\"><a href ng-click=\"selectPage(page.number, $event)\">{{page.text}}</a></li>\n" +
            "  <li ng-if=\"::directionLinks\" ng-class=\"{disabled: noNext()||ngDisabled}\" class=\"pagination-next\"><a href ng-click=\"selectPage(page + 1, $event)\">{{::getText('next')}}</a></li>\n" +
            "  <li ng-if=\"::boundaryLinks\" ng-class=\"{disabled: noNext()||ngDisabled}\" class=\"pagination-last\"><a href ng-click=\"selectPage(totalPages, $event)\">{{::getText('last')}}</a></li>\n" +
            "</ul>\n" +
            "");
    }]);
    angular.module("uib/template/tooltip/tooltip-html-popup.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/tooltip/tooltip-html-popup.html",
            "<div class=\"tooltip\"\n" +
            "  tooltip-animation-class=\"fade\"\n" +
            "  uib-tooltip-classes\n" +
            "  ng-class=\"{ in: isOpen() }\">\n" +
            "  <div class=\"tooltip-arrow\"></div>\n" +
            "  <div class=\"tooltip-inner\" ng-bind-html=\"contentExp()\"></div>\n" +
            "</div>\n" +
            "");
    }]);
    angular.module("uib/template/tooltip/tooltip-popup.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/tooltip/tooltip-popup.html",
            "<div class=\"tooltip\"\n" +
            "  tooltip-animation-class=\"fade\"\n" +
            "  uib-tooltip-classes\n" +
            "  ng-class=\"{ in: isOpen() }\">\n" +
            "  <div class=\"tooltip-arrow\"></div>\n" +
            "  <div class=\"tooltip-inner\" ng-bind=\"content\"></div>\n" +
            "</div>\n" +
            "");
    }]);
    angular.module("uib/template/tooltip/tooltip-template-popup.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/tooltip/tooltip-template-popup.html",
            "<div class=\"tooltip\"\n" +
            "  tooltip-animation-class=\"fade\"\n" +
            "  uib-tooltip-classes\n" +
            "  ng-class=\"{ in: isOpen() }\">\n" +
            "  <div class=\"tooltip-arrow\"></div>\n" +
            "  <div class=\"tooltip-inner\"\n" +
            "    uib-tooltip-template-transclude=\"contentExp()\"\n" +
            "    tooltip-template-transclude-scope=\"originScope()\"></div>\n" +
            "</div>\n" +
            "");
    }]);
    angular.module("uib/template/popover/popover-html.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/popover/popover-html.html",
            "<div class=\"popover\"\n" +
            "  tooltip-animation-class=\"fade\"\n" +
            "  uib-tooltip-classes\n" +
            "  ng-class=\"{ in: isOpen() }\">\n" +
            "  <div class=\"arrow\"></div>\n" +
            "\n" +
            "  <div class=\"popover-inner\">\n" +
            "      <h3 class=\"popover-title\" ng-bind=\"title\" ng-if=\"title\"></h3>\n" +
            "      <div class=\"popover-content\" ng-bind-html=\"contentExp()\"></div>\n" +
            "  </div>\n" +
            "</div>\n" +
            "");
    }]);
    angular.module("uib/template/popover/popover-template.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/popover/popover-template.html",
            "<div class=\"popover\"\n" +
            "  tooltip-animation-class=\"fade\"\n" +
            "  uib-tooltip-classes\n" +
            "  ng-class=\"{ in: isOpen() }\">\n" +
            "  <div class=\"arrow\"></div>\n" +
            "\n" +
            "  <div class=\"popover-inner\">\n" +
            "      <h3 class=\"popover-title\" ng-bind=\"title\" ng-if=\"title\"></h3>\n" +
            "      <div class=\"popover-content\"\n" +
            "        uib-tooltip-template-transclude=\"contentExp()\"\n" +
            "        tooltip-template-transclude-scope=\"originScope()\"></div>\n" +
            "  </div>\n" +
            "</div>\n" +
            "");
    }]);
    angular.module("uib/template/popover/popover.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/popover/popover.html",
            "<div class=\"popover\"\n" +
            "  tooltip-animation-class=\"fade\"\n" +
            "  uib-tooltip-classes\n" +
            "  ng-class=\"{ in: isOpen() }\">\n" +
            "  <div class=\"arrow\"></div>\n" +
            "\n" +
            "  <div class=\"popover-inner\">\n" +
            "      <h3 class=\"popover-title\" ng-bind=\"title\" ng-if=\"title\"></h3>\n" +
            "      <div class=\"popover-content\" ng-bind=\"content\"></div>\n" +
            "  </div>\n" +
            "</div>\n" +
            "");
    }]);
    angular.module("uib/template/progressbar/bar.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/progressbar/bar.html",
            "<div class=\"progress-bar\" ng-class=\"type && 'progress-bar-' + type\" role=\"progressbar\" aria-valuenow=\"{{value}}\" aria-valuemin=\"0\" aria-valuemax=\"{{max}}\" ng-style=\"{width: (percent < 100 ? percent : 100) + '%'}\" aria-valuetext=\"{{percent | number:0}}%\" aria-labelledby=\"{{::title}}\" ng-transclude></div>\n" +
            "");
    }]);
    angular.module("uib/template/progressbar/progress.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/progressbar/progress.html",
            "<div class=\"progress\" ng-transclude aria-labelledby=\"{{::title}}\"></div>");
    }]);
    angular.module("uib/template/progressbar/progressbar.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/progressbar/progressbar.html",
            "<div class=\"progress\">\n" +
            "  <div class=\"progress-bar\" ng-class=\"type && 'progress-bar-' + type\" role=\"progressbar\" aria-valuenow=\"{{value}}\" aria-valuemin=\"0\" aria-valuemax=\"{{max}}\" ng-style=\"{width: (percent < 100 ? percent : 100) + '%'}\" aria-valuetext=\"{{percent | number:0}}%\" aria-labelledby=\"{{::title}}\" ng-transclude></div>\n" +
            "</div>\n" +
            "");
    }]);
    angular.module("uib/template/rating/rating.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/rating/rating.html",
            "<span ng-mouseleave=\"reset()\" ng-keydown=\"onKeydown($event)\" tabindex=\"0\" role=\"slider\" aria-valuemin=\"0\" aria-valuemax=\"{{range.length}}\" aria-valuenow=\"{{value}}\">\n" +
            "    <span ng-repeat-start=\"r in range track by $index\" class=\"sr-only\">({{ $index < value ? '*' : ' ' }})</span>\n" +
            "    <i ng-repeat-end ng-mouseenter=\"enter($index + 1)\" ng-click=\"rate($index + 1)\" class=\"glyphicon\" ng-class=\"$index < value && (r.stateOn || 'glyphicon-star') || (r.stateOff || 'glyphicon-star-empty')\" ng-attr-title=\"{{r.title}}\" aria-valuetext=\"{{r.title}}\"></i>\n" +
            "</span>\n" +
            "");
    }]);
    angular.module("uib/template/tabs/tab.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/tabs/tab.html",
            "<li ng-class=\"{active: active, disabled: disabled}\" class=\"uib-tab\">\n" +
            "  <a href ng-click=\"select()\" uib-tab-heading-transclude>{{heading}}</a>\n" +
            "</li>\n" +
            "");
    }]);
    angular.module("uib/template/tabs/tabset.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/tabs/tabset.html",
            "<div>\n" +
            "  <ul class=\"nav nav-{{type || 'tabs'}}\" ng-class=\"{'nav-stacked': vertical, 'nav-justified': justified}\" ng-transclude></ul>\n" +
            "  <div class=\"tab-content\">\n" +
            "    <div class=\"tab-pane\" \n" +
            "         ng-repeat=\"tab in tabs\" \n" +
            "         ng-class=\"{active: tab.active}\"\n" +
            "         uib-tab-content-transclude=\"tab\">\n" +
            "    </div>\n" +
            "  </div>\n" +
            "</div>\n" +
            "");
    }]);
    angular.module("uib/template/timepicker/timepicker.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/timepicker/timepicker.html",
            "<table class=\"uib-timepicker\">\n" +
            "  <tbody>\n" +
            "    <tr class=\"text-center\" ng-show=\"::showSpinners\">\n" +
            "      <td class=\"uib-increment hours\"><a ng-click=\"incrementHours()\" ng-class=\"{disabled: noIncrementHours()}\" class=\"btn btn-link\" ng-disabled=\"noIncrementHours()\" tabindex=\"{{::tabindex}}\"><span class=\"glyphicon glyphicon-chevron-up\"></span></a></td>\n" +
            "      <td>&nbsp;</td>\n" +
            "      <td class=\"uib-increment minutes\"><a ng-click=\"incrementMinutes()\" ng-class=\"{disabled: noIncrementMinutes()}\" class=\"btn btn-link\" ng-disabled=\"noIncrementMinutes()\" tabindex=\"{{::tabindex}}\"><span class=\"glyphicon glyphicon-chevron-up\"></span></a></td>\n" +
            "      <td ng-show=\"showSeconds\">&nbsp;</td>\n" +
            "      <td ng-show=\"showSeconds\" class=\"uib-increment seconds\"><a ng-click=\"incrementSeconds()\" ng-class=\"{disabled: noIncrementSeconds()}\" class=\"btn btn-link\" ng-disabled=\"noIncrementSeconds()\" tabindex=\"{{::tabindex}}\"><span class=\"glyphicon glyphicon-chevron-up\"></span></a></td>\n" +
            "      <td ng-show=\"showMeridian\"></td>\n" +
            "    </tr>\n" +
            "    <tr>\n" +
            "      <td class=\"form-group uib-time hours\" ng-class=\"{'has-error': invalidHours}\">\n" +
            "        <input style=\"width:50px;\" type=\"text\" placeholder=\"HH\" ng-model=\"hours\" ng-change=\"updateHours()\" class=\"form-control text-center\" ng-readonly=\"::readonlyInput\" maxlength=\"2\" tabindex=\"{{::tabindex}}\" ng-disabled=\"noIncrementHours()\" ng-blur=\"blur()\">\n" +
            "      </td>\n" +
            "      <td class=\"uib-separator\">:</td>\n" +
            "      <td class=\"form-group uib-time minutes\" ng-class=\"{'has-error': invalidMinutes}\">\n" +
            "        <input style=\"width:50px;\" type=\"text\" placeholder=\"MM\" ng-model=\"minutes\" ng-change=\"updateMinutes()\" class=\"form-control text-center\" ng-readonly=\"::readonlyInput\" maxlength=\"2\" tabindex=\"{{::tabindex}}\" ng-disabled=\"noIncrementMinutes()\" ng-blur=\"blur()\">\n" +
            "      </td>\n" +
            "      <td ng-show=\"showSeconds\" class=\"uib-separator\">:</td>\n" +
            "      <td class=\"form-group uib-time seconds\" ng-class=\"{'has-error': invalidSeconds}\" ng-show=\"showSeconds\">\n" +
            "        <input style=\"width:50px;\" type=\"text\" placeholder=\"SS\" ng-model=\"seconds\" ng-change=\"updateSeconds()\" class=\"form-control text-center\" ng-readonly=\"readonlyInput\" maxlength=\"2\" tabindex=\"{{::tabindex}}\" ng-disabled=\"noIncrementSeconds()\" ng-blur=\"blur()\">\n" +
            "      </td>\n" +
            "      <td ng-show=\"showMeridian\" class=\"uib-time am-pm\"><button type=\"button\" ng-class=\"{disabled: noToggleMeridian()}\" class=\"btn btn-default text-center\" ng-click=\"toggleMeridian()\" ng-disabled=\"noToggleMeridian()\" tabindex=\"{{::tabindex}}\">{{meridian}}</button></td>\n" +
            "    </tr>\n" +
            "    <tr class=\"text-center\" ng-show=\"::showSpinners\">\n" +
            "      <td class=\"uib-decrement hours\"><a ng-click=\"decrementHours()\" ng-class=\"{disabled: noDecrementHours()}\" class=\"btn btn-link\" ng-disabled=\"noDecrementHours()\" tabindex=\"{{::tabindex}}\"><span class=\"glyphicon glyphicon-chevron-down\"></span></a></td>\n" +
            "      <td>&nbsp;</td>\n" +
            "      <td class=\"uib-decrement minutes\"><a ng-click=\"decrementMinutes()\" ng-class=\"{disabled: noDecrementMinutes()}\" class=\"btn btn-link\" ng-disabled=\"noDecrementMinutes()\" tabindex=\"{{::tabindex}}\"><span class=\"glyphicon glyphicon-chevron-down\"></span></a></td>\n" +
            "      <td ng-show=\"showSeconds\">&nbsp;</td>\n" +
            "      <td ng-show=\"showSeconds\" class=\"uib-decrement seconds\"><a ng-click=\"decrementSeconds()\" ng-class=\"{disabled: noDecrementSeconds()}\" class=\"btn btn-link\" ng-disabled=\"noDecrementSeconds()\" tabindex=\"{{::tabindex}}\"><span class=\"glyphicon glyphicon-chevron-down\"></span></a></td>\n" +
            "      <td ng-show=\"showMeridian\"></td>\n" +
            "    </tr>\n" +
            "  </tbody>\n" +
            "</table>\n" +
            "");
    }]);
    angular.module("uib/template/typeahead/typeahead-match.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/typeahead/typeahead-match.html",
            "<a href\n" +
            "   tabindex=\"-1\"\n" +
            "   ng-bind-html=\"match.label | uibTypeaheadHighlight:query\"\n" +
            "   ng-attr-title=\"{{match.label}}\"></a>\n" +
            "");
    }]);
    angular.module("uib/template/typeahead/typeahead-popup.html", []).run(["$templateCache", function($templateCache) {
        $templateCache.put("uib/template/typeahead/typeahead-popup.html",
            "<ul class=\"dropdown-menu\" ng-show=\"isOpen() && !moveInProgress\" ng-style=\"{top: position().top+'px', left: position().left+'px'}\" role=\"listbox\" aria-hidden=\"{{!isOpen()}}\">\n" +
            "    <li ng-repeat=\"match in matches track by $index\" ng-class=\"{active: isActive($index) }\" ng-mouseenter=\"selectActive($index)\" ng-click=\"selectMatch($index, $event)\" role=\"option\" id=\"{{::match.id}}\">\n" +
            "        <div uib-typeahead-match index=\"$index\" match=\"match\" query=\"query\" template-url=\"templateUrl\"></div>\n" +
            "    </li>\n" +
            "</ul>\n" +
            "");
    }]);
    angular.module('ui.bootstrap.carousel').run(function() {
        !angular.$$csp().noInlineStyle && angular.element(document).find('head').prepend('<style type="text/css">.ng-animate.item:not(.left):not(.right){-webkit-transition:0s ease-in-out left;transition:0s ease-in-out left}</style>');
    });
    angular.module('ui.bootstrap.datepicker').run(function() {
        !angular.$$csp().noInlineStyle && angular.element(document).find('head').prepend('<style type="text/css">.uib-datepicker .uib-title{width:100%;}.uib-day button,.uib-month button,.uib-year button{min-width:100%;}.uib-datepicker-popup.dropdown-menu{display:block;}.uib-button-bar{padding:10px 9px 2px;}</style>');
    });
    angular.module('ui.bootstrap.timepicker').run(function() {
        !angular.$$csp().noInlineStyle && angular.element(document).find('head').prepend('<style type="text/css">.uib-time input{width:50px;}</style>');
    });
    angular.module('ui.bootstrap.typeahead').run(function() {
        !angular.$$csp().noInlineStyle && angular.element(document).find('head').prepend('<style type="text/css">[uib-typeahead-popup].dropdown-menu{display:block;}</style>');
    });;
    /*! RESOURCE: /scripts/moment-2.8.3.js */
    (function(undefined) {
        var moment,
            VERSION = '2.8.3',
            globalScope = typeof global !== 'undefined' ? global : this,
            oldGlobalMoment,
            round = Math.round,
            hasOwnProperty = Object.prototype.hasOwnProperty,
            i,
            YEAR = 0,
            MONTH = 1,
            DATE = 2,
            HOUR = 3,
            MINUTE = 4,
            SECOND = 5,
            MILLISECOND = 6,
            locales = {},
            momentProperties = [],
            hasModule = (typeof module !== 'undefined' && module.exports),
            aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
            aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,
            isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,
            formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g,
            localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,
            parseTokenOneOrTwoDigits = /\d\d?/,
            parseTokenOneToThreeDigits = /\d{1,3}/,
            parseTokenOneToFourDigits = /\d{1,4}/,
            parseTokenOneToSixDigits = /[+\-]?\d{1,6}/,
            parseTokenDigits = /\d+/,
            parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,
            parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi,
            parseTokenT = /T/i,
            parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/,
            parseTokenOrdinal = /\d{1,2}/,
            parseTokenOneDigit = /\d/,
            parseTokenTwoDigits = /\d\d/,
            parseTokenThreeDigits = /\d{3}/,
            parseTokenFourDigits = /\d{4}/,
            parseTokenSixDigits = /[+-]?\d{6}/,
            parseTokenSignedNumber = /[+-]?\d+/,
            isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,
            isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',
            isoDates = [
                ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/],
                ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/],
                ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/],
                ['GGGG-[W]WW', /\d{4}-W\d{2}/],
                ['YYYY-DDD', /\d{4}-\d{3}/]
            ],
            isoTimes = [
                ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/],
                ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
                ['HH:mm', /(T| )\d\d:\d\d/],
                ['HH', /(T| )\d\d/]
            ],
            parseTimezoneChunker = /([\+\-]|\d\d)/gi,
            proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),
            unitMillisecondFactors = {
                'Milliseconds': 1,
                'Seconds': 1e3,
                'Minutes': 6e4,
                'Hours': 36e5,
                'Days': 864e5,
                'Months': 2592e6,
                'Years': 31536e6
            },
            unitAliases = {
                ms: 'millisecond',
                s: 'second',
                m: 'minute',
                h: 'hour',
                d: 'day',
                D: 'date',
                w: 'week',
                W: 'isoWeek',
                M: 'month',
                Q: 'quarter',
                y: 'year',
                DDD: 'dayOfYear',
                e: 'weekday',
                E: 'isoWeekday',
                gg: 'weekYear',
                GG: 'isoWeekYear'
            },
            camelFunctions = {
                dayofyear: 'dayOfYear',
                isoweekday: 'isoWeekday',
                isoweek: 'isoWeek',
                weekyear: 'weekYear',
                isoweekyear: 'isoWeekYear'
            },
            formatFunctions = {},
            relativeTimeThresholds = {
                s: 45,
                m: 45,
                h: 22,
                d: 26,
                M: 11
            },
            ordinalizeTokens = 'DDD w W M D d'.split(' '),
            paddedTokens = 'M D H h m s w W'.split(' '),
            formatTokenFunctions = {
                M: function() {
                    return this.month() + 1;
                },
                MMM: function(format) {
                    return this.localeData().monthsShort(this, format);
                },
                MMMM: function(format) {
                    return this.localeData().months(this, format);
                },
                D: function() {
                    return this.date();
                },
                DDD: function() {
                    return this.dayOfYear();
                },
                d: function() {
                    return this.day();
                },
                dd: function(format) {
                    return this.localeData().weekdaysMin(this, format);
                },
                ddd: function(format) {
                    return this.localeData().weekdaysShort(this, format);
                },
                dddd: function(format) {
                    return this.localeData().weekdays(this, format);
                },
                w: function() {
                    return this.week();
                },
                W: function() {
                    return this.isoWeek();
                },
                YY: function() {
                    return leftZeroFill(this.year() % 100, 2);
                },
                YYYY: function() {
                    return leftZeroFill(this.year(), 4);
                },
                YYYYY: function() {
                    return leftZeroFill(this.year(), 5);
                },
                YYYYYY: function() {
                    var y = this.year(),
                        sign = y >= 0 ? '+' : '-';
                    return sign + leftZeroFill(Math.abs(y), 6);
                },
                gg: function() {
                    return leftZeroFill(this.weekYear() % 100, 2);
                },
                gggg: function() {
                    return leftZeroFill(this.weekYear(), 4);
                },
                ggggg: function() {
                    return leftZeroFill(this.weekYear(), 5);
                },
                GG: function() {
                    return leftZeroFill(this.isoWeekYear() % 100, 2);
                },
                GGGG: function() {
                    return leftZeroFill(this.isoWeekYear(), 4);
                },
                GGGGG: function() {
                    return leftZeroFill(this.isoWeekYear(), 5);
                },
                e: function() {
                    return this.weekday();
                },
                E: function() {
                    return this.isoWeekday();
                },
                a: function() {
                    return this.localeData().meridiem(this.hours(), this.minutes(), true);
                },
                A: function() {
                    return this.localeData().meridiem(this.hours(), this.minutes(), false);
                },
                H: function() {
                    return this.hours();
                },
                h: function() {
                    return this.hours() % 12 || 12;
                },
                m: function() {
                    return this.minutes();
                },
                s: function() {
                    return this.seconds();
                },
                S: function() {
                    return toInt(this.milliseconds() / 100);
                },
                SS: function() {
                    return leftZeroFill(toInt(this.milliseconds() / 10), 2);
                },
                SSS: function() {
                    return leftZeroFill(this.milliseconds(), 3);
                },
                SSSS: function() {
                    return leftZeroFill(this.milliseconds(), 3);
                },
                Z: function() {
                    var a = -this.zone(),
                        b = '+';
                    if (a < 0) {
                        a = -a;
                        b = '-';
                    }
                    return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2);
                },
                ZZ: function() {
                    var a = -this.zone(),
                        b = '+';
                    if (a < 0) {
                        a = -a;
                        b = '-';
                    }
                    return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2);
                },
                z: function() {
                    return this.zoneAbbr();
                },
                zz: function() {
                    return this.zoneName();
                },
                X: function() {
                    return this.unix();
                },
                Q: function() {
                    return this.quarter();
                }
            },
            deprecations = {},
            lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin'];
    
        function dfl(a, b, c) {
            switch (arguments.length) {
                case 2:
                    return a != null ? a : b;
                case 3:
                    return a != null ? a : b != null ? b : c;
                default:
                    throw new Error('Implement me');
            }
        }
    
        function hasOwnProp(a, b) {
            return hasOwnProperty.call(a, b);
        }
    
        function defaultParsingFlags() {
            return {
                empty: false,
                unusedTokens: [],
                unusedInput: [],
                overflow: -2,
                charsLeftOver: 0,
                nullInput: false,
                invalidMonth: null,
                invalidFormat: false,
                userInvalidated: false,
                iso: false
            };
        }
    
        function printMsg(msg) {
            if (moment.suppressDeprecationWarnings === false &&
                typeof console !== 'undefined' && console.warn) {
                console.warn('Deprecation warning: ' + msg);
            }
        }
    
        function deprecate(msg, fn) {
            var firstTime = true;
            return extend(function() {
                if (firstTime) {
                    printMsg(msg);
                    firstTime = false;
                }
                return fn.apply(this, arguments);
            }, fn);
        }
    
        function deprecateSimple(name, msg) {
            if (!deprecations[name]) {
                printMsg(msg);
                deprecations[name] = true;
            }
        }
    
        function padToken(func, count) {
            return function(a) {
                return leftZeroFill(func.call(this, a), count);
            };
        }
    
        function ordinalizeToken(func, period) {
            return function(a) {
                return this.localeData().ordinal(func.call(this, a), period);
            };
        }
        while (ordinalizeTokens.length) {
            i = ordinalizeTokens.pop();
            formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i);
        }
        while (paddedTokens.length) {
            i = paddedTokens.pop();
            formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2);
        }
        formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3);
    
        function Locale() {}
    
        function Moment(config, skipOverflow) {
            if (skipOverflow !== false) {
                checkOverflow(config);
            }
            copyConfig(this, config);
            this._d = new Date(+config._d);
        }
    
        function Duration(duration) {
            var normalizedInput = normalizeObjectUnits(duration),
                years = normalizedInput.year || 0,
                quarters = normalizedInput.quarter || 0,
                months = normalizedInput.month || 0,
                weeks = normalizedInput.week || 0,
                days = normalizedInput.day || 0,
                hours = normalizedInput.hour || 0,
                minutes = normalizedInput.minute || 0,
                seconds = normalizedInput.second || 0,
                milliseconds = normalizedInput.millisecond || 0;
            this._milliseconds = +milliseconds +
                seconds * 1e3 +
                minutes * 6e4 +
                hours * 36e5;
            this._days = +days +
                weeks * 7;
            this._months = +months +
                quarters * 3 +
                years * 12;
            this._data = {};
            this._locale = moment.localeData();
            this._bubble();
        }
    
        function extend(a, b) {
            for (var i in b) {
                if (hasOwnProp(b, i)) {
                    a[i] = b[i];
                }
            }
            if (hasOwnProp(b, 'toString')) {
                a.toString = b.toString;
            }
            if (hasOwnProp(b, 'valueOf')) {
                a.valueOf = b.valueOf;
            }
            return a;
        }
    
        function copyConfig(to, from) {
            var i, prop, val;
            if (typeof from._isAMomentObject !== 'undefined') {
                to._isAMomentObject = from._isAMomentObject;
            }
            if (typeof from._i !== 'undefined') {
                to._i = from._i;
            }
            if (typeof from._f !== 'undefined') {
                to._f = from._f;
            }
            if (typeof from._l !== 'undefined') {
                to._l = from._l;
            }
            if (typeof from._strict !== 'undefined') {
                to._strict = from._strict;
            }
            if (typeof from._tzm !== 'undefined') {
                to._tzm = from._tzm;
            }
            if (typeof from._isUTC !== 'undefined') {
                to._isUTC = from._isUTC;
            }
            if (typeof from._offset !== 'undefined') {
                to._offset = from._offset;
            }
            if (typeof from._pf !== 'undefined') {
                to._pf = from._pf;
            }
            if (typeof from._locale !== 'undefined') {
                to._locale = from._locale;
            }
            if (momentProperties.length > 0) {
                for (i in momentProperties) {
                    prop = momentProperties[i];
                    val = from[prop];
                    if (typeof val !== 'undefined') {
                        to[prop] = val;
                    }
                }
            }
            return to;
        }
    
        function absRound(number) {
            if (number < 0) {
                return Math.ceil(number);
            } else {
                return Math.floor(number);
            }
        }
    
        function leftZeroFill(number, targetLength, forceSign) {
            var output = '' + Math.abs(number),
                sign = number >= 0;
            while (output.length < targetLength) {
                output = '0' + output;
            }
            return (sign ? (forceSign ? '+' : '') : '-') + output;
        }
    
        function positiveMomentsDifference(base, other) {
            var res = {
                milliseconds: 0,
                months: 0
            };
            res.months = other.month() - base.month() +
                (other.year() - base.year()) * 12;
            if (base.clone().add(res.months, 'M').isAfter(other)) {
                --res.months;
            }
            res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
            return res;
        }
    
        function momentsDifference(base, other) {
            var res;
            other = makeAs(other, base);
            if (base.isBefore(other)) {
                res = positiveMomentsDifference(base, other);
            } else {
                res = positiveMomentsDifference(other, base);
                res.milliseconds = -res.milliseconds;
                res.months = -res.months;
            }
            return res;
        }
    
        function createAdder(direction, name) {
            return function(val, period) {
                var dur, tmp;
                if (period !== null && !isNaN(+period)) {
                    deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');
                    tmp = val;
                    val = period;
                    period = tmp;
                }
                val = typeof val === 'string' ? +val : val;
                dur = moment.duration(val, period);
                addOrSubtractDurationFromMoment(this, dur, direction);
                return this;
            };
        }
    
        function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) {
            var milliseconds = duration._milliseconds,
                days = duration._days,
                months = duration._months;
            updateOffset = updateOffset == null ? true : updateOffset;
            if (milliseconds) {
                mom._d.setTime(+mom._d + milliseconds * isAdding);
            }
            if (days) {
                rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding);
            }
            if (months) {
                rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding);
            }
            if (updateOffset) {
                moment.updateOffset(mom, days || months);
            }
        }
    
        function isArray(input) {
            return Object.prototype.toString.call(input) === '[object Array]';
        }
    
        function isDate(input) {
            return Object.prototype.toString.call(input) === '[object Date]' ||
                input instanceof Date;
        }
    
        function compareArrays(array1, array2, dontConvert) {
            var len = Math.min(array1.length, array2.length),
                lengthDiff = Math.abs(array1.length - array2.length),
                diffs = 0,
                i;
            for (i = 0; i < len; i++) {
                if ((dontConvert && array1[i] !== array2[i]) ||
                    (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
                    diffs++;
                }
            }
            return diffs + lengthDiff;
        }
    
        function normalizeUnits(units) {
            if (units) {
                var lowered = units.toLowerCase().replace(/(.)s$/, '$1');
                units = unitAliases[units] || camelFunctions[lowered] || lowered;
            }
            return units;
        }
    
        function normalizeObjectUnits(inputObject) {
            var normalizedInput = {},
                normalizedProp,
                prop;
            for (prop in inputObject) {
                if (hasOwnProp(inputObject, prop)) {
                    normalizedProp = normalizeUnits(prop);
                    if (normalizedProp) {
                        normalizedInput[normalizedProp] = inputObject[prop];
                    }
                }
            }
            return normalizedInput;
        }
    
        function makeList(field) {
            var count, setter;
            if (field.indexOf('week') === 0) {
                count = 7;
                setter = 'day';
            } else if (field.indexOf('month') === 0) {
                count = 12;
                setter = 'month';
            } else {
                return;
            }
            moment[field] = function(format, index) {
                var i, getter,
                    method = moment._locale[field],
                    results = [];
                if (typeof format === 'number') {
                    index = format;
                    format = undefined;
                }
                getter = function(i) {
                    var m = moment().utc().set(setter, i);
                    return method.call(moment._locale, m, format || '');
                };
                if (index != null) {
                    return getter(index);
                } else {
                    for (i = 0; i < count; i++) {
                        results.push(getter(i));
                    }
                    return results;
                }
            };
        }
    
        function toInt(argumentForCoercion) {
            var coercedNumber = +argumentForCoercion,
                value = 0;
            if (coercedNumber !== 0 && isFinite(coercedNumber)) {
                if (coercedNumber >= 0) {
                    value = Math.floor(coercedNumber);
                } else {
                    value = Math.ceil(coercedNumber);
                }
            }
            return value;
        }
    
        function daysInMonth(year, month) {
            return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
        }
    
        function weeksInYear(year, dow, doy) {
            return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week;
        }
    
        function daysInYear(year) {
            return isLeapYear(year) ? 366 : 365;
        }
    
        function isLeapYear(year) {
            return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
        }
    
        function checkOverflow(m) {
            var overflow;
            if (m._a && m._pf.overflow === -2) {
                overflow =
                    m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH :
                    m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE :
                    m._a[HOUR] < 0 || m._a[HOUR] > 23 ? HOUR :
                    m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE :
                    m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND :
                    m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND :
                    -1;
                if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
                    overflow = DATE;
                }
                m._pf.overflow = overflow;
            }
        }
    
        function isValid(m) {
            if (m._isValid == null) {
                m._isValid = !isNaN(m._d.getTime()) &&
                    m._pf.overflow < 0 &&
                    !m._pf.empty &&
                    !m._pf.invalidMonth &&
                    !m._pf.nullInput &&
                    !m._pf.invalidFormat &&
                    !m._pf.userInvalidated;
                if (m._strict) {
                    m._isValid = m._isValid &&
                        m._pf.charsLeftOver === 0 &&
                        m._pf.unusedTokens.length === 0;
                }
            }
            return m._isValid;
        }
    
        function normalizeLocale(key) {
            return key ? key.toLowerCase().replace('_', '-') : key;
        }
    
        function chooseLocale(names) {
            var i = 0,
                j, next, locale, split;
            while (i < names.length) {
                split = normalizeLocale(names[i]).split('-');
                j = split.length;
                next = normalizeLocale(names[i + 1]);
                next = next ? next.split('-') : null;
                while (j > 0) {
                    locale = loadLocale(split.slice(0, j).join('-'));
                    if (locale) {
                        return locale;
                    }
                    if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
                        break;
                    }
                    j--;
                }
                i++;
            }
            return null;
        }
    
        function loadLocale(name) {
            var oldLocale = null;
            if (!locales[name] && hasModule) {
                try {
                    oldLocale = moment.locale();
                    require('./locale/' + name);
                    moment.locale(oldLocale);
                } catch (e) {}
            }
            return locales[name];
        }
    
        function makeAs(input, model) {
            return model._isUTC ? moment(input).zone(model._offset || 0) :
                moment(input).local();
        }
        extend(Locale.prototype, {
            set: function(config) {
                var prop, i;
                for (i in config) {
                    prop = config[i];
                    if (typeof prop === 'function') {
                        this[i] = prop;
                    } else {
                        this['_' + i] = prop;
                    }
                }
            },
            _months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
            months: function(m) {
                return this._months[m.month()];
            },
            _monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
            monthsShort: function(m) {
                return this._monthsShort[m.month()];
            },
            monthsParse: function(monthName) {
                var i, mom, regex;
                if (!this._monthsParse) {
                    this._monthsParse = [];
                }
                for (i = 0; i < 12; i++) {
                    if (!this._monthsParse[i]) {
                        mom = moment.utc([2000, i]);
                        regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
                        this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
                    }
                    if (this._monthsParse[i].test(monthName)) {
                        return i;
                    }
                }
            },
            _weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
            weekdays: function(m) {
                return this._weekdays[m.day()];
            },
            _weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
            weekdaysShort: function(m) {
                return this._weekdaysShort[m.day()];
            },
            _weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
            weekdaysMin: function(m) {
                return this._weekdaysMin[m.day()];
            },
            weekdaysParse: function(weekdayName) {
                var i, mom, regex;
                if (!this._weekdaysParse) {
                    this._weekdaysParse = [];
                }
                for (i = 0; i < 7; i++) {
                    if (!this._weekdaysParse[i]) {
                        mom = moment([2000, 1]).day(i);
                        regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
                        this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
                    }
                    if (this._weekdaysParse[i].test(weekdayName)) {
                        return i;
                    }
                }
            },
            _longDateFormat: {
                LT: 'h:mm A',
                L: 'MM/DD/YYYY',
                LL: 'MMMM D, YYYY',
                LLL: 'MMMM D, YYYY LT',
                LLLL: 'dddd, MMMM D, YYYY LT'
            },
            longDateFormat: function(key) {
                var output = this._longDateFormat[key];
                if (!output && this._longDateFormat[key.toUpperCase()]) {
                    output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function(val) {
                        return val.slice(1);
                    });
                    this._longDateFormat[key] = output;
                }
                return output;
            },
            isPM: function(input) {
                return ((input + '').toLowerCase().charAt(0) === 'p');
            },
            _meridiemParse: /[ap]\.?m?\.?/i,
            meridiem: function(hours, minutes, isLower) {
                if (hours > 11) {
                    return isLower ? 'pm' : 'PM';
                } else {
                    return isLower ? 'am' : 'AM';
                }
            },
            _calendar: {
                sameDay: '[Today at] LT',
                nextDay: '[Tomorrow at] LT',
                nextWeek: 'dddd [at] LT',
                lastDay: '[Yesterday at] LT',
                lastWeek: '[Last] dddd [at] LT',
                sameElse: 'L'
            },
            calendar: function(key, mom) {
                var output = this._calendar[key];
                return typeof output === 'function' ? output.apply(mom) : output;
            },
            _relativeTime: {
                future: 'in %s',
                past: '%s ago',
                s: 'a few seconds',
                m: 'a minute',
                mm: '%d minutes',
                h: 'an hour',
                hh: '%d hours',
                d: 'a day',
                dd: '%d days',
                M: 'a month',
                MM: '%d months',
                y: 'a year',
                yy: '%d years'
            },
            relativeTime: function(number, withoutSuffix, string, isFuture) {
                var output = this._relativeTime[string];
                return (typeof output === 'function') ?
                    output(number, withoutSuffix, string, isFuture) :
                    output.replace(/%d/i, number);
            },
            pastFuture: function(diff, output) {
                var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
                return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
            },
            ordinal: function(number) {
                return this._ordinal.replace('%d', number);
            },
            _ordinal: '%d',
            preparse: function(string) {
                return string;
            },
            postformat: function(string) {
                return string;
            },
            week: function(mom) {
                return weekOfYear(mom, this._week.dow, this._week.doy).week;
            },
            _week: {
                dow: 0,
                doy: 6
            },
            _invalidDate: 'Invalid date',
            invalidDate: function() {
                return this._invalidDate;
            }
        });
    
        function removeFormattingTokens(input) {
            if (input.match(/\[[\s\S]/)) {
                return input.replace(/^\[|\]$/g, '');
            }
            return input.replace(/\\/g, '');
        }
    
        function makeFormatFunction(format) {
            var array = format.match(formattingTokens),
                i, length;
            for (i = 0, length = array.length; i < length; i++) {
                if (formatTokenFunctions[array[i]]) {
                    array[i] = formatTokenFunctions[array[i]];
                } else {
                    array[i] = removeFormattingTokens(array[i]);
                }
            }
            return function(mom) {
                var output = '';
                for (i = 0; i < length; i++) {
                    output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
                }
                return output;
            };
        }
    
        function formatMoment(m, format) {
            if (!m.isValid()) {
                return m.localeData().invalidDate();
            }
            format = expandFormat(format, m.localeData());
            if (!formatFunctions[format]) {
                formatFunctions[format] = makeFormatFunction(format);
            }
            return formatFunctions[format](m);
        }
    
        function expandFormat(format, locale) {
            var i = 5;
    
            function replaceLongDateFormatTokens(input) {
                return locale.longDateFormat(input) || input;
            }
            localFormattingTokens.lastIndex = 0;
            while (i >= 0 && localFormattingTokens.test(format)) {
                format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
                localFormattingTokens.lastIndex = 0;
                i -= 1;
            }
            return format;
        }
    
        function getParseRegexForToken(token, config) {
            var a, strict = config._strict;
            switch (token) {
                case 'Q':
                    return parseTokenOneDigit;
                case 'DDDD':
                    return parseTokenThreeDigits;
                case 'YYYY':
                case 'GGGG':
                case 'gggg':
                    return strict ? parseTokenFourDigits : parseTokenOneToFourDigits;
                case 'Y':
                case 'G':
                case 'g':
                    return parseTokenSignedNumber;
                case 'YYYYYY':
                case 'YYYYY':
                case 'GGGGG':
                case 'ggggg':
                    return strict ? parseTokenSixDigits : parseTokenOneToSixDigits;
                case 'S':
                    if (strict) {
                        return parseTokenOneDigit;
                    }
                case 'SS':
                    if (strict) {
                        return parseTokenTwoDigits;
                    }
                case 'SSS':
                    if (strict) {
                        return parseTokenThreeDigits;
                    }
                case 'DDD':
                    return parseTokenOneToThreeDigits;
                case 'MMM':
                case 'MMMM':
                case 'dd':
                case 'ddd':
                case 'dddd':
                    return parseTokenWord;
                case 'a':
                case 'A':
                    return config._locale._meridiemParse;
                case 'X':
                    return parseTokenTimestampMs;
                case 'Z':
                case 'ZZ':
                    return parseTokenTimezone;
                case 'T':
                    return parseTokenT;
                case 'SSSS':
                    return parseTokenDigits;
                case 'MM':
                case 'DD':
                case 'YY':
                case 'GG':
                case 'gg':
                case 'HH':
                case 'hh':
                case 'mm':
                case 'ss':
                case 'ww':
                case 'WW':
                    return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits;
                case 'M':
                case 'D':
                case 'd':
                case 'H':
                case 'h':
                case 'm':
                case 's':
                case 'w':
                case 'W':
                case 'e':
                case 'E':
                    return parseTokenOneOrTwoDigits;
                case 'Do':
                    return parseTokenOrdinal;
                default:
                    a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i'));
                    return a;
            }
        }
    
        function timezoneMinutesFromString(string) {
            string = string || '';
            var possibleTzMatches = (string.match(parseTokenTimezone) || []),
                tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [],
                parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
                minutes = +(parts[1] * 60) + toInt(parts[2]);
            return parts[0] === '+' ? -minutes : minutes;
        }
    
        function addTimeToArrayFromToken(token, input, config) {
            var a, datePartArray = config._a;
            switch (token) {
                case 'Q':
                    if (input != null) {
                        datePartArray[MONTH] = (toInt(input) - 1) * 3;
                    }
                    break;
                case 'M':
                case 'MM':
                    if (input != null) {
                        datePartArray[MONTH] = toInt(input) - 1;
                    }
                    break;
                case 'MMM':
                case 'MMMM':
                    a = config._locale.monthsParse(input);
                    if (a != null) {
                        datePartArray[MONTH] = a;
                    } else {
                        config._pf.invalidMonth = input;
                    }
                    break;
                case 'D':
                case 'DD':
                    if (input != null) {
                        datePartArray[DATE] = toInt(input);
                    }
                    break;
                case 'Do':
                    if (input != null) {
                        datePartArray[DATE] = toInt(parseInt(input, 10));
                    }
                    break;
                case 'DDD':
                case 'DDDD':
                    if (input != null) {
                        config._dayOfYear = toInt(input);
                    }
                    break;
                case 'YY':
                    datePartArray[YEAR] = moment.parseTwoDigitYear(input);
                    break;
                case 'YYYY':
                case 'YYYYY':
                case 'YYYYYY':
                    datePartArray[YEAR] = toInt(input);
                    break;
                case 'a':
                case 'A':
                    config._isPm = config._locale.isPM(input);
                    break;
                case 'H':
                case 'HH':
                case 'h':
                case 'hh':
                    datePartArray[HOUR] = toInt(input);
                    break;
                case 'm':
                case 'mm':
                    datePartArray[MINUTE] = toInt(input);
                    break;
                case 's':
                case 'ss':
                    datePartArray[SECOND] = toInt(input);
                    break;
                case 'S':
                case 'SS':
                case 'SSS':
                case 'SSSS':
                    datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000);
                    break;
                case 'X':
                    config._d = new Date(parseFloat(input) * 1000);
                    break;
                case 'Z':
                case 'ZZ':
                    config._useUTC = true;
                    config._tzm = timezoneMinutesFromString(input);
                    break;
                case 'dd':
                case 'ddd':
                case 'dddd':
                    a = config._locale.weekdaysParse(input);
                    if (a != null) {
                        config._w = config._w || {};
                        config._w['d'] = a;
                    } else {
                        config._pf.invalidWeekday = input;
                    }
                    break;
                case 'w':
                case 'ww':
                case 'W':
                case 'WW':
                case 'd':
                case 'e':
                case 'E':
                    token = token.substr(0, 1);
                case 'gggg':
                case 'GGGG':
                case 'GGGGG':
                    token = token.substr(0, 2);
                    if (input) {
                        config._w = config._w || {};
                        config._w[token] = toInt(input);
                    }
                    break;
                case 'gg':
                case 'GG':
                    config._w = config._w || {};
                    config._w[token] = moment.parseTwoDigitYear(input);
            }
        }
    
        function dayOfYearFromWeekInfo(config) {
            var w, weekYear, week, weekday, dow, doy, temp;
            w = config._w;
            if (w.GG != null || w.W != null || w.E != null) {
                dow = 1;
                doy = 4;
                weekYear = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year);
                week = dfl(w.W, 1);
                weekday = dfl(w.E, 1);
            } else {
                dow = config._locale._week.dow;
                doy = config._locale._week.doy;
                weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year);
                week = dfl(w.w, 1);
                if (w.d != null) {
                    weekday = w.d;
                    if (weekday < dow) {
                        ++week;
                    }
                } else if (w.e != null) {
                    weekday = w.e + dow;
                } else {
                    weekday = dow;
                }
            }
            temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);
            config._a[YEAR] = temp.year;
            config._dayOfYear = temp.dayOfYear;
        }
    
        function dateFromConfig(config) {
            var i, date, input = [],
                currentDate, yearToUse;
            if (config._d) {
                return;
            }
            currentDate = currentDateArray(config);
            if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
                dayOfYearFromWeekInfo(config);
            }
            if (config._dayOfYear) {
                yearToUse = dfl(config._a[YEAR], currentDate[YEAR]);
                if (config._dayOfYear > daysInYear(yearToUse)) {
                    config._pf._overflowDayOfYear = true;
                }
                date = makeUTCDate(yearToUse, 0, config._dayOfYear);
                config._a[MONTH] = date.getUTCMonth();
                config._a[DATE] = date.getUTCDate();
            }
            for (i = 0; i < 3 && config._a[i] == null; ++i) {
                config._a[i] = input[i] = currentDate[i];
            }
            for (; i < 7; i++) {
                config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
            }
            config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input);
            if (config._tzm != null) {
                config._d.setUTCMinutes(config._d.getUTCMinutes() + config._tzm);
            }
        }
    
        function dateFromObject(config) {
            var normalizedInput;
            if (config._d) {
                return;
            }
            normalizedInput = normalizeObjectUnits(config._i);
            config._a = [
                normalizedInput.year,
                normalizedInput.month,
                normalizedInput.day,
                normalizedInput.hour,
                normalizedInput.minute,
                normalizedInput.second,
                normalizedInput.millisecond
            ];
            dateFromConfig(config);
        }
    
        function currentDateArray(config) {
            var now = new Date();
            if (config._useUTC) {
                return [
                    now.getUTCFullYear(),
                    now.getUTCMonth(),
                    now.getUTCDate()
                ];
            } else {
                return [now.getFullYear(), now.getMonth(), now.getDate()];
            }
        }
    
        function makeDateFromStringAndFormat(config) {
            if (config._f === moment.ISO_8601) {
                parseISO(config);
                return;
            }
            config._a = [];
            config._pf.empty = true;
            var string = '' + config._i,
                i, parsedInput, tokens, token, skipped,
                stringLength = string.length,
                totalParsedInputLength = 0;
            tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
            for (i = 0; i < tokens.length; i++) {
                token = tokens[i];
                parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
                if (parsedInput) {
                    skipped = string.substr(0, string.indexOf(parsedInput));
                    if (skipped.length > 0) {
                        config._pf.unusedInput.push(skipped);
                    }
                    string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
                    totalParsedInputLength += parsedInput.length;
                }
                if (formatTokenFunctions[token]) {
                    if (parsedInput) {
                        config._pf.empty = false;
                    } else {
                        config._pf.unusedTokens.push(token);
                    }
                    addTimeToArrayFromToken(token, parsedInput, config);
                } else if (config._strict && !parsedInput) {
                    config._pf.unusedTokens.push(token);
                }
            }
            config._pf.charsLeftOver = stringLength - totalParsedInputLength;
            if (string.length > 0) {
                config._pf.unusedInput.push(string);
            }
            if (config._isPm && config._a[HOUR] < 12) {
                config._a[HOUR] += 12;
            }
            if (config._isPm === false && config._a[HOUR] === 12) {
                config._a[HOUR] = 0;
            }
            dateFromConfig(config);
            checkOverflow(config);
        }
    
        function unescapeFormat(s) {
            return s.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function(matched, p1, p2, p3, p4) {
                return p1 || p2 || p3 || p4;
            });
        }
    
        function regexpEscape(s) {
            return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
        }
    
        function makeDateFromStringAndArray(config) {
            var tempConfig,
                bestMoment,
                scoreToBeat,
                i,
                currentScore;
            if (config._f.length === 0) {
                config._pf.invalidFormat = true;
                config._d = new Date(NaN);
                return;
            }
            for (i = 0; i < config._f.length; i++) {
                currentScore = 0;
                tempConfig = copyConfig({}, config);
                if (config._useUTC != null) {
                    tempConfig._useUTC = config._useUTC;
                }
                tempConfig._pf = defaultParsingFlags();
                tempConfig._f = config._f[i];
                makeDateFromStringAndFormat(tempConfig);
                if (!isValid(tempConfig)) {
                    continue;
                }
                currentScore += tempConfig._pf.charsLeftOver;
                currentScore += tempConfig._pf.unusedTokens.length * 10;
                tempConfig._pf.score = currentScore;
                if (scoreToBeat == null || currentScore < scoreToBeat) {
                    scoreToBeat = currentScore;
                    bestMoment = tempConfig;
                }
            }
            extend(config, bestMoment || tempConfig);
        }
    
        function parseISO(config) {
            var i, l,
                string = config._i,
                match = isoRegex.exec(string);
            if (match) {
                config._pf.iso = true;
                for (i = 0, l = isoDates.length; i < l; i++) {
                    if (isoDates[i][1].exec(string)) {
                        config._f = isoDates[i][0] + (match[6] || ' ');
                        break;
                    }
                }
                for (i = 0, l = isoTimes.length; i < l; i++) {
                    if (isoTimes[i][1].exec(string)) {
                        config._f += isoTimes[i][0];
                        break;
                    }
                }
                if (string.match(parseTokenTimezone)) {
                    config._f += 'Z';
                }
                makeDateFromStringAndFormat(config);
            } else {
                config._isValid = false;
            }
        }
    
        function makeDateFromString(config) {
            parseISO(config);
            if (config._isValid === false) {
                delete config._isValid;
                moment.createFromInputFallback(config);
            }
        }
    
        function map(arr, fn) {
            var res = [],
                i;
            for (i = 0; i < arr.length; ++i) {
                res.push(fn(arr[i], i));
            }
            return res;
        }
    
        function makeDateFromInput(config) {
            var input = config._i,
                matched;
            if (input === undefined) {
                config._d = new Date();
            } else if (isDate(input)) {
                config._d = new Date(+input);
            } else if ((matched = aspNetJsonRegex.exec(input)) !== null) {
                config._d = new Date(+matched[1]);
            } else if (typeof input === 'string') {
                makeDateFromString(config);
            } else if (isArray(input)) {
                config._a = map(input.slice(0), function(obj) {
                    return parseInt(obj, 10);
                });
                dateFromConfig(config);
            } else if (typeof(input) === 'object') {
                dateFromObject(config);
            } else if (typeof(input) === 'number') {
                config._d = new Date(input);
            } else {
                moment.createFromInputFallback(config);
            }
        }
    
        function makeDate(y, m, d, h, M, s, ms) {
            var date = new Date(y, m, d, h, M, s, ms);
            if (y < 1970) {
                date.setFullYear(y);
            }
            return date;
        }
    
        function makeUTCDate(y) {
            var date = new Date(Date.UTC.apply(null, arguments));
            if (y < 1970) {
                date.setUTCFullYear(y);
            }
            return date;
        }
    
        function parseWeekday(input, locale) {
            if (typeof input === 'string') {
                if (!isNaN(input)) {
                    input = parseInt(input, 10);
                } else {
                    input = locale.weekdaysParse(input);
                    if (typeof input !== 'number') {
                        return null;
                    }
                }
            }
            return input;
        }
    
        function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
            return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
        }
    
        function relativeTime(posNegDuration, withoutSuffix, locale) {
            var duration = moment.duration(posNegDuration).abs(),
                seconds = round(duration.as('s')),
                minutes = round(duration.as('m')),
                hours = round(duration.as('h')),
                days = round(duration.as('d')),
                months = round(duration.as('M')),
                years = round(duration.as('y')),
                args = seconds < relativeTimeThresholds.s && ['s', seconds] ||
                minutes === 1 && ['m'] ||
                minutes < relativeTimeThresholds.m && ['mm', minutes] ||
                hours === 1 && ['h'] ||
                hours < relativeTimeThresholds.h && ['hh', hours] ||
                days === 1 && ['d'] ||
                days < relativeTimeThresholds.d && ['dd', days] ||
                months === 1 && ['M'] ||
                months < relativeTimeThresholds.M && ['MM', months] ||
                years === 1 && ['y'] || ['yy', years];
            args[2] = withoutSuffix;
            args[3] = +posNegDuration > 0;
            args[4] = locale;
            return substituteTimeAgo.apply({}, args);
        }
    
        function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
            var end = firstDayOfWeekOfYear - firstDayOfWeek,
                daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
                adjustedMoment;
            if (daysToDayOfWeek > end) {
                daysToDayOfWeek -= 7;
            }
            if (daysToDayOfWeek < end - 7) {
                daysToDayOfWeek += 7;
            }
            adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd');
            return {
                week: Math.ceil(adjustedMoment.dayOfYear() / 7),
                year: adjustedMoment.year()
            };
        }
    
        function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
            var d = makeUTCDate(year, 0, 1).getUTCDay(),
                daysToAdd, dayOfYear;
            d = d === 0 ? 7 : d;
            weekday = weekday != null ? weekday : firstDayOfWeek;
            daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);
            dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;
            return {
                year: dayOfYear > 0 ? year : year - 1,
                dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
            };
        }
    
        function makeMoment(config) {
            var input = config._i,
                format = config._f;
            config._locale = config._locale || moment.localeData(config._l);
            if (input === null || (format === undefined && input === '')) {
                return moment.invalid({
                    nullInput: true
                });
            }
            if (typeof input === 'string') {
                config._i = input = config._locale.preparse(input);
            }
            if (moment.isMoment(input)) {
                return new Moment(input, true);
            } else if (format) {
                if (isArray(format)) {
                    makeDateFromStringAndArray(config);
                } else {
                    makeDateFromStringAndFormat(config);
                }
            } else {
                makeDateFromInput(config);
            }
            return new Moment(config);
        }
        moment = function(input, format, locale, strict) {
            var c;
            if (typeof(locale) === 'boolean') {
                strict = locale;
                locale = undefined;
            }
            c = {};
            c._isAMomentObject = true;
            c._i = input;
            c._f = format;
            c._l = locale;
            c._strict = strict;
            c._isUTC = false;
            c._pf = defaultParsingFlags();
            return makeMoment(c);
        };
        moment.suppressDeprecationWarnings = false;
        moment.createFromInputFallback = deprecate(
            'moment construction falls back to js Date. This is ' +
            'discouraged and will be removed in upcoming major ' +
            'release. Please refer to ' +
            'https://github.com/moment/moment/issues/1407 for more info.',
            function(config) {
                config._d = new Date(config._i);
            }
        );
    
        function pickBy(fn, moments) {
            var res, i;
            if (moments.length === 1 && isArray(moments[0])) {
                moments = moments[0];
            }
            if (!moments.length) {
                return moment();
            }
            res = moments[0];
            for (i = 1; i < moments.length; ++i) {
                if (moments[i][fn](res)) {
                    res = moments[i];
                }
            }
            return res;
        }
        moment.min = function() {
            var args = [].slice.call(arguments, 0);
            return pickBy('isBefore', args);
        };
        moment.max = function() {
            var args = [].slice.call(arguments, 0);
            return pickBy('isAfter', args);
        };
        moment.utc = function(input, format, locale, strict) {
            var c;
            if (typeof(locale) === 'boolean') {
                strict = locale;
                locale = undefined;
            }
            c = {};
            c._isAMomentObject = true;
            c._useUTC = true;
            c._isUTC = true;
            c._l = locale;
            c._i = input;
            c._f = format;
            c._strict = strict;
            c._pf = defaultParsingFlags();
            return makeMoment(c).utc();
        };
        moment.unix = function(input) {
            return moment(input * 1000);
        };
        moment.duration = function(input, key) {
            var duration = input,
                match = null,
                sign,
                ret,
                parseIso,
                diffRes;
            if (moment.isDuration(input)) {
                duration = {
                    ms: input._milliseconds,
                    d: input._days,
                    M: input._months
                };
            } else if (typeof input === 'number') {
                duration = {};
                if (key) {
                    duration[key] = input;
                } else {
                    duration.milliseconds = input;
                }
            } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) {
                sign = (match[1] === '-') ? -1 : 1;
                duration = {
                    y: 0,
                    d: toInt(match[DATE]) * sign,
                    h: toInt(match[HOUR]) * sign,
                    m: toInt(match[MINUTE]) * sign,
                    s: toInt(match[SECOND]) * sign,
                    ms: toInt(match[MILLISECOND]) * sign
                };
            } else if (!!(match = isoDurationRegex.exec(input))) {
                sign = (match[1] === '-') ? -1 : 1;
                parseIso = function(inp) {
                    var res = inp && parseFloat(inp.replace(',', '.'));
                    return (isNaN(res) ? 0 : res) * sign;
                };
                duration = {
                    y: parseIso(match[2]),
                    M: parseIso(match[3]),
                    d: parseIso(match[4]),
                    h: parseIso(match[5]),
                    m: parseIso(match[6]),
                    s: parseIso(match[7]),
                    w: parseIso(match[8])
                };
            } else if (typeof duration === 'object' &&
                ('from' in duration || 'to' in duration)) {
                diffRes = momentsDifference(moment(duration.from), moment(duration.to));
                duration = {};
                duration.ms = diffRes.milliseconds;
                duration.M = diffRes.months;
            }
            ret = new Duration(duration);
            if (moment.isDuration(input) && hasOwnProp(input, '_locale')) {
                ret._locale = input._locale;
            }
            return ret;
        };
        moment.version = VERSION;
        moment.defaultFormat = isoFormat;
        moment.ISO_8601 = function() {};
        moment.momentProperties = momentProperties;
        moment.updateOffset = function() {};
        moment.relativeTimeThreshold = function(threshold, limit) {
            if (relativeTimeThresholds[threshold] === undefined) {
                return false;
            }
            if (limit === undefined) {
                return relativeTimeThresholds[threshold];
            }
            relativeTimeThresholds[threshold] = limit;
            return true;
        };
        moment.lang = deprecate(
            'moment.lang is deprecated. Use moment.locale instead.',
            function(key, value) {
                return moment.locale(key, value);
            }
        );
        moment.locale = function(key, values) {
            var data;
            if (key) {
                if (typeof(values) !== 'undefined') {
                    data = moment.defineLocale(key, values);
                } else {
                    data = moment.localeData(key);
                }
                if (data) {
                    moment.duration._locale = moment._locale = data;
                }
            }
            return moment._locale._abbr;
        };
        moment.defineLocale = function(name, values) {
            if (values !== null) {
                values.abbr = name;
                if (!locales[name]) {
                    locales[name] = new Locale();
                }
                locales[name].set(values);
                moment.locale(name);
                return locales[name];
            } else {
                delete locales[name];
                return null;
            }
        };
        moment.langData = deprecate(
            'moment.langData is deprecated. Use moment.localeData instead.',
            function(key) {
                return moment.localeData(key);
            }
        );
        moment.localeData = function(key) {
            var locale;
            if (key && key._locale && key._locale._abbr) {
                key = key._locale._abbr;
            }
            if (!key) {
                return moment._locale;
            }
            if (!isArray(key)) {
                locale = loadLocale(key);
                if (locale) {
                    return locale;
                }
                key = [key];
            }
            return chooseLocale(key);
        };
        moment.isMoment = function(obj) {
            return obj instanceof Moment ||
                (obj != null && hasOwnProp(obj, '_isAMomentObject'));
        };
        moment.isDuration = function(obj) {
            return obj instanceof Duration;
        };
        for (i = lists.length - 1; i >= 0; --i) {
            makeList(lists[i]);
        }
        moment.normalizeUnits = function(units) {
            return normalizeUnits(units);
        };
        moment.invalid = function(flags) {
            var m = moment.utc(NaN);
            if (flags != null) {
                extend(m._pf, flags);
            } else {
                m._pf.userInvalidated = true;
            }
            return m;
        };
        moment.parseZone = function() {
            return moment.apply(null, arguments).parseZone();
        };
        moment.parseTwoDigitYear = function(input) {
            return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
        };
        extend(moment.fn = Moment.prototype, {
            clone: function() {
                return moment(this);
            },
            valueOf: function() {
                return +this._d + ((this._offset || 0) * 60000);
            },
            unix: function() {
                return Math.floor(+this / 1000);
            },
            toString: function() {
                return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
            },
            toDate: function() {
                return this._offset ? new Date(+this) : this._d;
            },
            toISOString: function() {
                var m = moment(this).utc();
                if (0 < m.year() && m.year() <= 9999) {
                    return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
                } else {
                    return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
                }
            },
            toArray: function() {
                var m = this;
                return [
                    m.year(),
                    m.month(),
                    m.date(),
                    m.hours(),
                    m.minutes(),
                    m.seconds(),
                    m.milliseconds()
                ];
            },
            isValid: function() {
                return isValid(this);
            },
            isDSTShifted: function() {
                if (this._a) {
                    return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0;
                }
                return false;
            },
            parsingFlags: function() {
                return extend({}, this._pf);
            },
            invalidAt: function() {
                return this._pf.overflow;
            },
            utc: function(keepLocalTime) {
                return this.zone(0, keepLocalTime);
            },
            local: function(keepLocalTime) {
                if (this._isUTC) {
                    this.zone(0, keepLocalTime);
                    this._isUTC = false;
                    if (keepLocalTime) {
                        this.add(this._dateTzOffset(), 'm');
                    }
                }
                return this;
            },
            format: function(inputString) {
                var output = formatMoment(this, inputString || moment.defaultFormat);
                return this.localeData().postformat(output);
            },
            add: createAdder(1, 'add'),
            subtract: createAdder(-1, 'subtract'),
            diff: function(input, units, asFloat) {
                var that = makeAs(input, this),
                    zoneDiff = (this.zone() - that.zone()) * 6e4,
                    diff, output, daysAdjust;
                units = normalizeUnits(units);
                if (units === 'year' || units === 'month') {
                    diff = (this.daysInMonth() + that.daysInMonth()) * 432e5;
                    output = ((this.year() - that.year()) * 12) + (this.month() - that.month());
                    daysAdjust = (this - moment(this).startOf('month')) -
                        (that - moment(that).startOf('month'));
                    daysAdjust -= ((this.zone() - moment(this).startOf('month').zone()) -
                        (that.zone() - moment(that).startOf('month').zone())) * 6e4;
                    output += daysAdjust / diff;
                    if (units === 'year') {
                        output = output / 12;
                    }
                } else {
                    diff = (this - that);
                    output = units === 'second' ? diff / 1e3 :
                        units === 'minute' ? diff / 6e4 :
                        units === 'hour' ? diff / 36e5 :
                        units === 'day' ? (diff - zoneDiff) / 864e5 :
                        units === 'week' ? (diff - zoneDiff) / 6048e5 :
                        diff;
                }
                return asFloat ? output : absRound(output);
            },
            from: function(time, withoutSuffix) {
                return moment.duration({
                    to: this,
                    from: time
                }).locale(this.locale()).humanize(!withoutSuffix);
            },
            fromNow: function(withoutSuffix) {
                return this.from(moment(), withoutSuffix);
            },
            calendar: function(time) {
                var now = time || moment(),
                    sod = makeAs(now, this).startOf('day'),
                    diff = this.diff(sod, 'days', true),
                    format = diff < -6 ? 'sameElse' :
                    diff < -1 ? 'lastWeek' :
                    diff < 0 ? 'lastDay' :
                    diff < 1 ? 'sameDay' :
                    diff < 2 ? 'nextDay' :
                    diff < 7 ? 'nextWeek' : 'sameElse';
                return this.format(this.localeData().calendar(format, this));
            },
            isLeapYear: function() {
                return isLeapYear(this.year());
            },
            isDST: function() {
                return (this.zone() < this.clone().month(0).zone() ||
                    this.zone() < this.clone().month(5).zone());
            },
            day: function(input) {
                var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
                if (input != null) {
                    input = parseWeekday(input, this.localeData());
                    return this.add(input - day, 'd');
                } else {
                    return day;
                }
            },
            month: makeAccessor('Month', true),
            startOf: function(units) {
                units = normalizeUnits(units);
                switch (units) {
                    case 'year':
                        this.month(0);
                    case 'quarter':
                    case 'month':
                        this.date(1);
                    case 'week':
                    case 'isoWeek':
                    case 'day':
                        this.hours(0);
                    case 'hour':
                        this.minutes(0);
                    case 'minute':
                        this.seconds(0);
                    case 'second':
                        this.milliseconds(0);
                }
                if (units === 'week') {
                    this.weekday(0);
                } else if (units === 'isoWeek') {
                    this.isoWeekday(1);
                }
                if (units === 'quarter') {
                    this.month(Math.floor(this.month() / 3) * 3);
                }
                return this;
            },
            endOf: function(units) {
                units = normalizeUnits(units);
                return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
            },
            isAfter: function(input, units) {
                units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
                if (units === 'millisecond') {
                    input = moment.isMoment(input) ? input : moment(input);
                    return +this > +input;
                } else {
                    return +this.clone().startOf(units) > +moment(input).startOf(units);
                }
            },
            isBefore: function(input, units) {
                units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
                if (units === 'millisecond') {
                    input = moment.isMoment(input) ? input : moment(input);
                    return +this < +input;
                } else {
                    return +this.clone().startOf(units) < +moment(input).startOf(units);
                }
            },
            isSame: function(input, units) {
                units = normalizeUnits(units || 'millisecond');
                if (units === 'millisecond') {
                    input = moment.isMoment(input) ? input : moment(input);
                    return +this === +input;
                } else {
                    return +this.clone().startOf(units) === +makeAs(input, this).startOf(units);
                }
            },
            min: deprecate(
                'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
                function(other) {
                    other = moment.apply(null, arguments);
                    return other < this ? this : other;
                }
            ),
            max: deprecate(
                'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
                function(other) {
                    other = moment.apply(null, arguments);
                    return other > this ? this : other;
                }
            ),
            zone: function(input, keepLocalTime) {
                var offset = this._offset || 0,
                    localAdjust;
                if (input != null) {
                    if (typeof input === 'string') {
                        input = timezoneMinutesFromString(input);
                    }
                    if (Math.abs(input) < 16) {
                        input = input * 60;
                    }
                    if (!this._isUTC && keepLocalTime) {
                        localAdjust = this._dateTzOffset();
                    }
                    this._offset = input;
                    this._isUTC = true;
                    if (localAdjust != null) {
                        this.subtract(localAdjust, 'm');
                    }
                    if (offset !== input) {
                        if (!keepLocalTime || this._changeInProgress) {
                            addOrSubtractDurationFromMoment(this,
                                moment.duration(offset - input, 'm'), 1, false);
                        } else if (!this._changeInProgress) {
                            this._changeInProgress = true;
                            moment.updateOffset(this, true);
                            this._changeInProgress = null;
                        }
                    }
                } else {
                    return this._isUTC ? offset : this._dateTzOffset();
                }
                return this;
            },
            zoneAbbr: function() {
                return this._isUTC ? 'UTC' : '';
            },
            zoneName: function() {
                return this._isUTC ? 'Coordinated Universal Time' : '';
            },
            parseZone: function() {
                if (this._tzm) {
                    this.zone(this._tzm);
                } else if (typeof this._i === 'string') {
                    this.zone(this._i);
                }
                return this;
            },
            hasAlignedHourOffset: function(input) {
                if (!input) {
                    input = 0;
                } else {
                    input = moment(input).zone();
                }
                return (this.zone() - input) % 60 === 0;
            },
            daysInMonth: function() {
                return daysInMonth(this.year(), this.month());
            },
            dayOfYear: function(input) {
                var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;
                return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
            },
            quarter: function(input) {
                return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
            },
            weekYear: function(input) {
                var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;
                return input == null ? year : this.add((input - year), 'y');
            },
            isoWeekYear: function(input) {
                var year = weekOfYear(this, 1, 4).year;
                return input == null ? year : this.add((input - year), 'y');
            },
            week: function(input) {
                var week = this.localeData().week(this);
                return input == null ? week : this.add((input - week) * 7, 'd');
            },
            isoWeek: function(input) {
                var week = weekOfYear(this, 1, 4).week;
                return input == null ? week : this.add((input - week) * 7, 'd');
            },
            weekday: function(input) {
                var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
                return input == null ? weekday : this.add(input - weekday, 'd');
            },
            isoWeekday: function(input) {
                return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
            },
            isoWeeksInYear: function() {
                return weeksInYear(this.year(), 1, 4);
            },
            weeksInYear: function() {
                var weekInfo = this.localeData()._week;
                return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
            },
            get: function(units) {
                units = normalizeUnits(units);
                return this[units]();
            },
            set: function(units, value) {
                units = normalizeUnits(units);
                if (typeof this[units] === 'function') {
                    this[units](value);
                }
                return this;
            },
            locale: function(key) {
                var newLocaleData;
                if (key === undefined) {
                    return this._locale._abbr;
                } else {
                    newLocaleData = moment.localeData(key);
                    if (newLocaleData != null) {
                        this._locale = newLocaleData;
                    }
                    return this;
                }
            },
            lang: deprecate(
                'moment().lang() is deprecated. Use moment().localeData() instead.',
                function(key) {
                    if (key === undefined) {
                        return this.localeData();
                    } else {
                        return this.locale(key);
                    }
                }
            ),
            localeData: function() {
                return this._locale;
            },
            _dateTzOffset: function() {
                return Math.round(this._d.getTimezoneOffset() / 15) * 15;
            }
        });
    
        function rawMonthSetter(mom, value) {
            var dayOfMonth;
            if (typeof value === 'string') {
                value = mom.localeData().monthsParse(value);
                if (typeof value !== 'number') {
                    return mom;
                }
            }
            dayOfMonth = Math.min(mom.date(),
                daysInMonth(mom.year(), value));
            mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
            return mom;
        }
    
        function rawGetter(mom, unit) {
            return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();
        }
    
        function rawSetter(mom, unit, value) {
            if (unit === 'Month') {
                return rawMonthSetter(mom, value);
            } else {
                return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
            }
        }
    
        function makeAccessor(unit, keepTime) {
            return function(value) {
                if (value != null) {
                    rawSetter(this, unit, value);
                    moment.updateOffset(this, keepTime);
                    return this;
                } else {
                    return rawGetter(this, unit);
                }
            };
        }
        moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false);
        moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false);
        moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false);
        moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true);
        moment.fn.date = makeAccessor('Date', true);
        moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true));
        moment.fn.year = makeAccessor('FullYear', true);
        moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true));
        moment.fn.days = moment.fn.day;
        moment.fn.months = moment.fn.month;
        moment.fn.weeks = moment.fn.week;
        moment.fn.isoWeeks = moment.fn.isoWeek;
        moment.fn.quarters = moment.fn.quarter;
        moment.fn.toJSON = moment.fn.toISOString;
    
        function daysToYears(days) {
            return days * 400 / 146097;
        }
    
        function yearsToDays(years) {
            return years * 146097 / 400;
        }
        extend(moment.duration.fn = Duration.prototype, {
            _bubble: function() {
                var milliseconds = this._milliseconds,
                    days = this._days,
                    months = this._months,
                    data = this._data,
                    seconds, minutes, hours, years = 0;
                data.milliseconds = milliseconds % 1000;
                seconds = absRound(milliseconds / 1000);
                data.seconds = seconds % 60;
                minutes = absRound(seconds / 60);
                data.minutes = minutes % 60;
                hours = absRound(minutes / 60);
                data.hours = hours % 24;
                days += absRound(hours / 24);
                years = absRound(daysToYears(days));
                days -= absRound(yearsToDays(years));
                months += absRound(days / 30);
                days %= 30;
                years += absRound(months / 12);
                months %= 12;
                data.days = days;
                data.months = months;
                data.years = years;
            },
            abs: function() {
                this._milliseconds = Math.abs(this._milliseconds);
                this._days = Math.abs(this._days);
                this._months = Math.abs(this._months);
                this._data.milliseconds = Math.abs(this._data.milliseconds);
                this._data.seconds = Math.abs(this._data.seconds);
                this._data.minutes = Math.abs(this._data.minutes);
                this._data.hours = Math.abs(this._data.hours);
                this._data.months = Math.abs(this._data.months);
                this._data.years = Math.abs(this._data.years);
                return this;
            },
            weeks: function() {
                return absRound(this.days() / 7);
            },
            valueOf: function() {
                return this._milliseconds +
                    this._days * 864e5 +
                    (this._months % 12) * 2592e6 +
                    toInt(this._months / 12) * 31536e6;
            },
            humanize: function(withSuffix) {
                var output = relativeTime(this, !withSuffix, this.localeData());
                if (withSuffix) {
                    output = this.localeData().pastFuture(+this, output);
                }
                return this.localeData().postformat(output);
            },
            add: function(input, val) {
                var dur = moment.duration(input, val);
                this._milliseconds += dur._milliseconds;
                this._days += dur._days;
                this._months += dur._months;
                this._bubble();
                return this;
            },
            subtract: function(input, val) {
                var dur = moment.duration(input, val);
                this._milliseconds -= dur._milliseconds;
                this._days -= dur._days;
                this._months -= dur._months;
                this._bubble();
                return this;
            },
            get: function(units) {
                units = normalizeUnits(units);
                return this[units.toLowerCase() + 's']();
            },
            as: function(units) {
                var days, months;
                units = normalizeUnits(units);
                if (units === 'month' || units === 'year') {
                    days = this._days + this._milliseconds / 864e5;
                    months = this._months + daysToYears(days) * 12;
                    return units === 'month' ? months : months / 12;
                } else {
                    days = this._days + yearsToDays(this._months / 12);
                    switch (units) {
                        case 'week':
                            return days / 7 + this._milliseconds / 6048e5;
                        case 'day':
                            return days + this._milliseconds / 864e5;
                        case 'hour':
                            return days * 24 + this._milliseconds / 36e5;
                        case 'minute':
                            return days * 24 * 60 + this._milliseconds / 6e4;
                        case 'second':
                            return days * 24 * 60 * 60 + this._milliseconds / 1000;
                        case 'millisecond':
                            return Math.floor(days * 24 * 60 * 60 * 1000) + this._milliseconds;
                        default:
                            throw new Error('Unknown unit ' + units);
                    }
                }
            },
            lang: moment.fn.lang,
            locale: moment.fn.locale,
            toIsoString: deprecate(
                'toIsoString() is deprecated. Please use toISOString() instead ' +
                '(notice the capitals)',
                function() {
                    return this.toISOString();
                }
            ),
            toISOString: function() {
                var years = Math.abs(this.years()),
                    months = Math.abs(this.months()),
                    days = Math.abs(this.days()),
                    hours = Math.abs(this.hours()),
                    minutes = Math.abs(this.minutes()),
                    seconds = Math.abs(this.seconds() + this.milliseconds() / 1000);
                if (!this.asSeconds()) {
                    return 'P0D';
                }
                return (this.asSeconds() < 0 ? '-' : '') +
                    'P' +
                    (years ? years + 'Y' : '') +
                    (months ? months + 'M' : '') +
                    (days ? days + 'D' : '') +
                    ((hours || minutes || seconds) ? 'T' : '') +
                    (hours ? hours + 'H' : '') +
                    (minutes ? minutes + 'M' : '') +
                    (seconds ? seconds + 'S' : '');
            },
            localeData: function() {
                return this._locale;
            }
        });
        moment.duration.fn.toString = moment.duration.fn.toISOString;
    
        function makeDurationGetter(name) {
            moment.duration.fn[name] = function() {
                return this._data[name];
            };
        }
        for (i in unitMillisecondFactors) {
            if (hasOwnProp(unitMillisecondFactors, i)) {
                makeDurationGetter(i.toLowerCase());
            }
        }
        moment.duration.fn.asMilliseconds = function() {
            return this.as('ms');
        };
        moment.duration.fn.asSeconds = function() {
            return this.as('s');
        };
        moment.duration.fn.asMinutes = function() {
            return this.as('m');
        };
        moment.duration.fn.asHours = function() {
            return this.as('h');
        };
        moment.duration.fn.asDays = function() {
            return this.as('d');
        };
        moment.duration.fn.asWeeks = function() {
            return this.as('weeks');
        };
        moment.duration.fn.asMonths = function() {
            return this.as('M');
        };
        moment.duration.fn.asYears = function() {
            return this.as('y');
        };
        moment.locale('en', {
            ordinal: function(number) {
                var b = number % 10,
                    output = (toInt(number % 100 / 10) === 1) ? 'th' :
                    (b === 1) ? 'st' :
                    (b === 2) ? 'nd' :
                    (b === 3) ? 'rd' : 'th';
                return number + output;
            }
        });
    
        function makeGlobal(shouldDeprecate) {
            if (typeof ender !== 'undefined') {
                return;
            }
            oldGlobalMoment = globalScope.moment;
            if (shouldDeprecate) {
                globalScope.moment = deprecate(
                    'Accessing Moment through the global scope is ' +
                    'deprecated, and will be removed in an upcoming ' +
                    'release.',
                    moment);
            } else {
                globalScope.moment = moment;
            }
        }
        if (hasModule) {
            module.exports = moment;
        } else if (typeof define === 'function' && define.amd) {
            define('moment', function(require, exports, module) {
                if (module.config && module.config() && module.config().noGlobal === true) {
                    globalScope.moment = oldGlobalMoment;
                }
                return moment;
            });
            makeGlobal(true);
        } else {
            makeGlobal();
        }
    }).call(this);;
    /*! RESOURCE: /scripts/thirdparty/select2/select2.js */
    (function($) {
        if (typeof $.fn.each2 == "undefined") {
            $.extend($.fn, {
                each2: function(c) {
                    var j = $([0]),
                        i = -1,
                        l = this.length;
                    while (
                        ++i < l &&
                        (j.context = j[0] = this[i]) &&
                        c.call(j[0], i, j) !== false
                    );
                    return this;
                }
            });
        }
    })(jQuery);
    (function($, undefined) {
        "use strict";
        if (window.Select2 !== undefined) {
            return;
        }
        var KEY, AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer,
            lastMousePosition = {
                x: 0,
                y: 0
            },
            $document, scrollBarDimensions,
            KEY = {
                TAB: 9,
                ENTER: 13,
                ESC: 27,
                SPACE: 32,
                LEFT: 37,
                UP: 38,
                RIGHT: 39,
                DOWN: 40,
                SHIFT: 16,
                CTRL: 17,
                ALT: 18,
                PAGE_UP: 33,
                PAGE_DOWN: 34,
                HOME: 36,
                END: 35,
                BACKSPACE: 8,
                DELETE: 46,
                isArrow: function(k) {
                    k = k.which ? k.which : k;
                    switch (k) {
                        case KEY.LEFT:
                        case KEY.RIGHT:
                        case KEY.UP:
                        case KEY.DOWN:
                            return true;
                    }
                    return false;
                },
                isControl: function(e) {
                    var k = e.which;
                    switch (k) {
                        case KEY.SHIFT:
                        case KEY.CTRL:
                        case KEY.ALT:
                            return true;
                    }
                    if (e.metaKey) return true;
                    return false;
                },
                isFunctionKey: function(k) {
                    k = k.which ? k.which : k;
                    return k >= 112 && k <= 123;
                }
            },
            MEASURE_SCROLLBAR_TEMPLATE = "<div class='select2-measure-scrollbar'></div>",
            DIACRITICS = {
                "\u24B6": "A",
                "\uFF21": "A",
                "\u00C0": "A",
                "\u00C1": "A",
                "\u00C2": "A",
                "\u1EA6": "A",
                "\u1EA4": "A",
                "\u1EAA": "A",
                "\u1EA8": "A",
                "\u00C3": "A",
                "\u0100": "A",
                "\u0102": "A",
                "\u1EB0": "A",
                "\u1EAE": "A",
                "\u1EB4": "A",
                "\u1EB2": "A",
                "\u0226": "A",
                "\u01E0": "A",
                "\u00C4": "A",
                "\u01DE": "A",
                "\u1EA2": "A",
                "\u00C5": "A",
                "\u01FA": "A",
                "\u01CD": "A",
                "\u0200": "A",
                "\u0202": "A",
                "\u1EA0": "A",
                "\u1EAC": "A",
                "\u1EB6": "A",
                "\u1E00": "A",
                "\u0104": "A",
                "\u023A": "A",
                "\u2C6F": "A",
                "\uA732": "AA",
                "\u00C6": "AE",
                "\u01FC": "AE",
                "\u01E2": "AE",
                "\uA734": "AO",
                "\uA736": "AU",
                "\uA738": "AV",
                "\uA73A": "AV",
                "\uA73C": "AY",
                "\u24B7": "B",
                "\uFF22": "B",
                "\u1E02": "B",
                "\u1E04": "B",
                "\u1E06": "B",
                "\u0243": "B",
                "\u0182": "B",
                "\u0181": "B",
                "\u24B8": "C",
                "\uFF23": "C",
                "\u0106": "C",
                "\u0108": "C",
                "\u010A": "C",
                "\u010C": "C",
                "\u00C7": "C",
                "\u1E08": "C",
                "\u0187": "C",
                "\u023B": "C",
                "\uA73E": "C",
                "\u24B9": "D",
                "\uFF24": "D",
                "\u1E0A": "D",
                "\u010E": "D",
                "\u1E0C": "D",
                "\u1E10": "D",
                "\u1E12": "D",
                "\u1E0E": "D",
                "\u0110": "D",
                "\u018B": "D",
                "\u018A": "D",
                "\u0189": "D",
                "\uA779": "D",
                "\u01F1": "DZ",
                "\u01C4": "DZ",
                "\u01F2": "Dz",
                "\u01C5": "Dz",
                "\u24BA": "E",
                "\uFF25": "E",
                "\u00C8": "E",
                "\u00C9": "E",
                "\u00CA": "E",
                "\u1EC0": "E",
                "\u1EBE": "E",
                "\u1EC4": "E",
                "\u1EC2": "E",
                "\u1EBC": "E",
                "\u0112": "E",
                "\u1E14": "E",
                "\u1E16": "E",
                "\u0114": "E",
                "\u0116": "E",
                "\u00CB": "E",
                "\u1EBA": "E",
                "\u011A": "E",
                "\u0204": "E",
                "\u0206": "E",
                "\u1EB8": "E",
                "\u1EC6": "E",
                "\u0228": "E",
                "\u1E1C": "E",
                "\u0118": "E",
                "\u1E18": "E",
                "\u1E1A": "E",
                "\u0190": "E",
                "\u018E": "E",
                "\u24BB": "F",
                "\uFF26": "F",
                "\u1E1E": "F",
                "\u0191": "F",
                "\uA77B": "F",
                "\u24BC": "G",
                "\uFF27": "G",
                "\u01F4": "G",
                "\u011C": "G",
                "\u1E20": "G",
                "\u011E": "G",
                "\u0120": "G",
                "\u01E6": "G",
                "\u0122": "G",
                "\u01E4": "G",
                "\u0193": "G",
                "\uA7A0": "G",
                "\uA77D": "G",
                "\uA77E": "G",
                "\u24BD": "H",
                "\uFF28": "H",
                "\u0124": "H",
                "\u1E22": "H",
                "\u1E26": "H",
                "\u021E": "H",
                "\u1E24": "H",
                "\u1E28": "H",
                "\u1E2A": "H",
                "\u0126": "H",
                "\u2C67": "H",
                "\u2C75": "H",
                "\uA78D": "H",
                "\u24BE": "I",
                "\uFF29": "I",
                "\u00CC": "I",
                "\u00CD": "I",
                "\u00CE": "I",
                "\u0128": "I",
                "\u012A": "I",
                "\u012C": "I",
                "\u0130": "I",
                "\u00CF": "I",
                "\u1E2E": "I",
                "\u1EC8": "I",
                "\u01CF": "I",
                "\u0208": "I",
                "\u020A": "I",
                "\u1ECA": "I",
                "\u012E": "I",
                "\u1E2C": "I",
                "\u0197": "I",
                "\u24BF": "J",
                "\uFF2A": "J",
                "\u0134": "J",
                "\u0248": "J",
                "\u24C0": "K",
                "\uFF2B": "K",
                "\u1E30": "K",
                "\u01E8": "K",
                "\u1E32": "K",
                "\u0136": "K",
                "\u1E34": "K",
                "\u0198": "K",
                "\u2C69": "K",
                "\uA740": "K",
                "\uA742": "K",
                "\uA744": "K",
                "\uA7A2": "K",
                "\u24C1": "L",
                "\uFF2C": "L",
                "\u013F": "L",
                "\u0139": "L",
                "\u013D": "L",
                "\u1E36": "L",
                "\u1E38": "L",
                "\u013B": "L",
                "\u1E3C": "L",
                "\u1E3A": "L",
                "\u0141": "L",
                "\u023D": "L",
                "\u2C62": "L",
                "\u2C60": "L",
                "\uA748": "L",
                "\uA746": "L",
                "\uA780": "L",
                "\u01C7": "LJ",
                "\u01C8": "Lj",
                "\u24C2": "M",
                "\uFF2D": "M",
                "\u1E3E": "M",
                "\u1E40": "M",
                "\u1E42": "M",
                "\u2C6E": "M",
                "\u019C": "M",
                "\u24C3": "N",
                "\uFF2E": "N",
                "\u01F8": "N",
                "\u0143": "N",
                "\u00D1": "N",
                "\u1E44": "N",
                "\u0147": "N",
                "\u1E46": "N",
                "\u0145": "N",
                "\u1E4A": "N",
                "\u1E48": "N",
                "\u0220": "N",
                "\u019D": "N",
                "\uA790": "N",
                "\uA7A4": "N",
                "\u01CA": "NJ",
                "\u01CB": "Nj",
                "\u24C4": "O",
                "\uFF2F": "O",
                "\u00D2": "O",
                "\u00D3": "O",
                "\u00D4": "O",
                "\u1ED2": "O",
                "\u1ED0": "O",
                "\u1ED6": "O",
                "\u1ED4": "O",
                "\u00D5": "O",
                "\u1E4C": "O",
                "\u022C": "O",
                "\u1E4E": "O",
                "\u014C": "O",
                "\u1E50": "O",
                "\u1E52": "O",
                "\u014E": "O",
                "\u022E": "O",
                "\u0230": "O",
                "\u00D6": "O",
                "\u022A": "O",
                "\u1ECE": "O",
                "\u0150": "O",
                "\u01D1": "O",
                "\u020C": "O",
                "\u020E": "O",
                "\u01A0": "O",
                "\u1EDC": "O",
                "\u1EDA": "O",
                "\u1EE0": "O",
                "\u1EDE": "O",
                "\u1EE2": "O",
                "\u1ECC": "O",
                "\u1ED8": "O",
                "\u01EA": "O",
                "\u01EC": "O",
                "\u00D8": "O",
                "\u01FE": "O",
                "\u0186": "O",
                "\u019F": "O",
                "\uA74A": "O",
                "\uA74C": "O",
                "\u01A2": "OI",
                "\uA74E": "OO",
                "\u0222": "OU",
                "\u24C5": "P",
                "\uFF30": "P",
                "\u1E54": "P",
                "\u1E56": "P",
                "\u01A4": "P",
                "\u2C63": "P",
                "\uA750": "P",
                "\uA752": "P",
                "\uA754": "P",
                "\u24C6": "Q",
                "\uFF31": "Q",
                "\uA756": "Q",
                "\uA758": "Q",
                "\u024A": "Q",
                "\u24C7": "R",
                "\uFF32": "R",
                "\u0154": "R",
                "\u1E58": "R",
                "\u0158": "R",
                "\u0210": "R",
                "\u0212": "R",
                "\u1E5A": "R",
                "\u1E5C": "R",
                "\u0156": "R",
                "\u1E5E": "R",
                "\u024C": "R",
                "\u2C64": "R",
                "\uA75A": "R",
                "\uA7A6": "R",
                "\uA782": "R",
                "\u24C8": "S",
                "\uFF33": "S",
                "\u1E9E": "S",
                "\u015A": "S",
                "\u1E64": "S",
                "\u015C": "S",
                "\u1E60": "S",
                "\u0160": "S",
                "\u1E66": "S",
                "\u1E62": "S",
                "\u1E68": "S",
                "\u0218": "S",
                "\u015E": "S",
                "\u2C7E": "S",
                "\uA7A8": "S",
                "\uA784": "S",
                "\u24C9": "T",
                "\uFF34": "T",
                "\u1E6A": "T",
                "\u0164": "T",
                "\u1E6C": "T",
                "\u021A": "T",
                "\u0162": "T",
                "\u1E70": "T",
                "\u1E6E": "T",
                "\u0166": "T",
                "\u01AC": "T",
                "\u01AE": "T",
                "\u023E": "T",
                "\uA786": "T",
                "\uA728": "TZ",
                "\u24CA": "U",
                "\uFF35": "U",
                "\u00D9": "U",
                "\u00DA": "U",
                "\u00DB": "U",
                "\u0168": "U",
                "\u1E78": "U",
                "\u016A": "U",
                "\u1E7A": "U",
                "\u016C": "U",
                "\u00DC": "U",
                "\u01DB": "U",
                "\u01D7": "U",
                "\u01D5": "U",
                "\u01D9": "U",
                "\u1EE6": "U",
                "\u016E": "U",
                "\u0170": "U",
                "\u01D3": "U",
                "\u0214": "U",
                "\u0216": "U",
                "\u01AF": "U",
                "\u1EEA": "U",
                "\u1EE8": "U",
                "\u1EEE": "U",
                "\u1EEC": "U",
                "\u1EF0": "U",
                "\u1EE4": "U",
                "\u1E72": "U",
                "\u0172": "U",
                "\u1E76": "U",
                "\u1E74": "U",
                "\u0244": "U",
                "\u24CB": "V",
                "\uFF36": "V",
                "\u1E7C": "V",
                "\u1E7E": "V",
                "\u01B2": "V",
                "\uA75E": "V",
                "\u0245": "V",
                "\uA760": "VY",
                "\u24CC": "W",
                "\uFF37": "W",
                "\u1E80": "W",
                "\u1E82": "W",
                "\u0174": "W",
                "\u1E86": "W",
                "\u1E84": "W",
                "\u1E88": "W",
                "\u2C72": "W",
                "\u24CD": "X",
                "\uFF38": "X",
                "\u1E8A": "X",
                "\u1E8C": "X",
                "\u24CE": "Y",
                "\uFF39": "Y",
                "\u1EF2": "Y",
                "\u00DD": "Y",
                "\u0176": "Y",
                "\u1EF8": "Y",
                "\u0232": "Y",
                "\u1E8E": "Y",
                "\u0178": "Y",
                "\u1EF6": "Y",
                "\u1EF4": "Y",
                "\u01B3": "Y",
                "\u024E": "Y",
                "\u1EFE": "Y",
                "\u24CF": "Z",
                "\uFF3A": "Z",
                "\u0179": "Z",
                "\u1E90": "Z",
                "\u017B": "Z",
                "\u017D": "Z",
                "\u1E92": "Z",
                "\u1E94": "Z",
                "\u01B5": "Z",
                "\u0224": "Z",
                "\u2C7F": "Z",
                "\u2C6B": "Z",
                "\uA762": "Z",
                "\u24D0": "a",
                "\uFF41": "a",
                "\u1E9A": "a",
                "\u00E0": "a",
                "\u00E1": "a",
                "\u00E2": "a",
                "\u1EA7": "a",
                "\u1EA5": "a",
                "\u1EAB": "a",
                "\u1EA9": "a",
                "\u00E3": "a",
                "\u0101": "a",
                "\u0103": "a",
                "\u1EB1": "a",
                "\u1EAF": "a",
                "\u1EB5": "a",
                "\u1EB3": "a",
                "\u0227": "a",
                "\u01E1": "a",
                "\u00E4": "a",
                "\u01DF": "a",
                "\u1EA3": "a",
                "\u00E5": "a",
                "\u01FB": "a",
                "\u01CE": "a",
                "\u0201": "a",
                "\u0203": "a",
                "\u1EA1": "a",
                "\u1EAD": "a",
                "\u1EB7": "a",
                "\u1E01": "a",
                "\u0105": "a",
                "\u2C65": "a",
                "\u0250": "a",
                "\uA733": "aa",
                "\u00E6": "ae",
                "\u01FD": "ae",
                "\u01E3": "ae",
                "\uA735": "ao",
                "\uA737": "au",
                "\uA739": "av",
                "\uA73B": "av",
                "\uA73D": "ay",
                "\u24D1": "b",
                "\uFF42": "b",
                "\u1E03": "b",
                "\u1E05": "b",
                "\u1E07": "b",
                "\u0180": "b",
                "\u0183": "b",
                "\u0253": "b",
                "\u24D2": "c",
                "\uFF43": "c",
                "\u0107": "c",
                "\u0109": "c",
                "\u010B": "c",
                "\u010D": "c",
                "\u00E7": "c",
                "\u1E09": "c",
                "\u0188": "c",
                "\u023C": "c",
                "\uA73F": "c",
                "\u2184": "c",
                "\u24D3": "d",
                "\uFF44": "d",
                "\u1E0B": "d",
                "\u010F": "d",
                "\u1E0D": "d",
                "\u1E11": "d",
                "\u1E13": "d",
                "\u1E0F": "d",
                "\u0111": "d",
                "\u018C": "d",
                "\u0256": "d",
                "\u0257": "d",
                "\uA77A": "d",
                "\u01F3": "dz",
                "\u01C6": "dz",
                "\u24D4": "e",
                "\uFF45": "e",
                "\u00E8": "e",
                "\u00E9": "e",
                "\u00EA": "e",
                "\u1EC1": "e",
                "\u1EBF": "e",
                "\u1EC5": "e",
                "\u1EC3": "e",
                "\u1EBD": "e",
                "\u0113": "e",
                "\u1E15": "e",
                "\u1E17": "e",
                "\u0115": "e",
                "\u0117": "e",
                "\u00EB": "e",
                "\u1EBB": "e",
                "\u011B": "e",
                "\u0205": "e",
                "\u0207": "e",
                "\u1EB9": "e",
                "\u1EC7": "e",
                "\u0229": "e",
                "\u1E1D": "e",
                "\u0119": "e",
                "\u1E19": "e",
                "\u1E1B": "e",
                "\u0247": "e",
                "\u025B": "e",
                "\u01DD": "e",
                "\u24D5": "f",
                "\uFF46": "f",
                "\u1E1F": "f",
                "\u0192": "f",
                "\uA77C": "f",
                "\u24D6": "g",
                "\uFF47": "g",
                "\u01F5": "g",
                "\u011D": "g",
                "\u1E21": "g",
                "\u011F": "g",
                "\u0121": "g",
                "\u01E7": "g",
                "\u0123": "g",
                "\u01E5": "g",
                "\u0260": "g",
                "\uA7A1": "g",
                "\u1D79": "g",
                "\uA77F": "g",
                "\u24D7": "h",
                "\uFF48": "h",
                "\u0125": "h",
                "\u1E23": "h",
                "\u1E27": "h",
                "\u021F": "h",
                "\u1E25": "h",
                "\u1E29": "h",
                "\u1E2B": "h",
                "\u1E96": "h",
                "\u0127": "h",
                "\u2C68": "h",
                "\u2C76": "h",
                "\u0265": "h",
                "\u0195": "hv",
                "\u24D8": "i",
                "\uFF49": "i",
                "\u00EC": "i",
                "\u00ED": "i",
                "\u00EE": "i",
                "\u0129": "i",
                "\u012B": "i",
                "\u012D": "i",
                "\u00EF": "i",
                "\u1E2F": "i",
                "\u1EC9": "i",
                "\u01D0": "i",
                "\u0209": "i",
                "\u020B": "i",
                "\u1ECB": "i",
                "\u012F": "i",
                "\u1E2D": "i",
                "\u0268": "i",
                "\u0131": "i",
                "\u24D9": "j",
                "\uFF4A": "j",
                "\u0135": "j",
                "\u01F0": "j",
                "\u0249": "j",
                "\u24DA": "k",
                "\uFF4B": "k",
                "\u1E31": "k",
                "\u01E9": "k",
                "\u1E33": "k",
                "\u0137": "k",
                "\u1E35": "k",
                "\u0199": "k",
                "\u2C6A": "k",
                "\uA741": "k",
                "\uA743": "k",
                "\uA745": "k",
                "\uA7A3": "k",
                "\u24DB": "l",
                "\uFF4C": "l",
                "\u0140": "l",
                "\u013A": "l",
                "\u013E": "l",
                "\u1E37": "l",
                "\u1E39": "l",
                "\u013C": "l",
                "\u1E3D": "l",
                "\u1E3B": "l",
                "\u017F": "l",
                "\u0142": "l",
                "\u019A": "l",
                "\u026B": "l",
                "\u2C61": "l",
                "\uA749": "l",
                "\uA781": "l",
                "\uA747": "l",
                "\u01C9": "lj",
                "\u24DC": "m",
                "\uFF4D": "m",
                "\u1E3F": "m",
                "\u1E41": "m",
                "\u1E43": "m",
                "\u0271": "m",
                "\u026F": "m",
                "\u24DD": "n",
                "\uFF4E": "n",
                "\u01F9": "n",
                "\u0144": "n",
                "\u00F1": "n",
                "\u1E45": "n",
                "\u0148": "n",
                "\u1E47": "n",
                "\u0146": "n",
                "\u1E4B": "n",
                "\u1E49": "n",
                "\u019E": "n",
                "\u0272": "n",
                "\u0149": "n",
                "\uA791": "n",
                "\uA7A5": "n",
                "\u01CC": "nj",
                "\u24DE": "o",
                "\uFF4F": "o",
                "\u00F2": "o",
                "\u00F3": "o",
                "\u00F4": "o",
                "\u1ED3": "o",
                "\u1ED1": "o",
                "\u1ED7": "o",
                "\u1ED5": "o",
                "\u00F5": "o",
                "\u1E4D": "o",
                "\u022D": "o",
                "\u1E4F": "o",
                "\u014D": "o",
                "\u1E51": "o",
                "\u1E53": "o",
                "\u014F": "o",
                "\u022F": "o",
                "\u0231": "o",
                "\u00F6": "o",
                "\u022B": "o",
                "\u1ECF": "o",
                "\u0151": "o",
                "\u01D2": "o",
                "\u020D": "o",
                "\u020F": "o",
                "\u01A1": "o",
                "\u1EDD": "o",
                "\u1EDB": "o",
                "\u1EE1": "o",
                "\u1EDF": "o",
                "\u1EE3": "o",
                "\u1ECD": "o",
                "\u1ED9": "o",
                "\u01EB": "o",
                "\u01ED": "o",
                "\u00F8": "o",
                "\u01FF": "o",
                "\u0254": "o",
                "\uA74B": "o",
                "\uA74D": "o",
                "\u0275": "o",
                "\u01A3": "oi",
                "\u0223": "ou",
                "\uA74F": "oo",
                "\u24DF": "p",
                "\uFF50": "p",
                "\u1E55": "p",
                "\u1E57": "p",
                "\u01A5": "p",
                "\u1D7D": "p",
                "\uA751": "p",
                "\uA753": "p",
                "\uA755": "p",
                "\u24E0": "q",
                "\uFF51": "q",
                "\u024B": "q",
                "\uA757": "q",
                "\uA759": "q",
                "\u24E1": "r",
                "\uFF52": "r",
                "\u0155": "r",
                "\u1E59": "r",
                "\u0159": "r",
                "\u0211": "r",
                "\u0213": "r",
                "\u1E5B": "r",
                "\u1E5D": "r",
                "\u0157": "r",
                "\u1E5F": "r",
                "\u024D": "r",
                "\u027D": "r",
                "\uA75B": "r",
                "\uA7A7": "r",
                "\uA783": "r",
                "\u24E2": "s",
                "\uFF53": "s",
                "\u00DF": "s",
                "\u015B": "s",
                "\u1E65": "s",
                "\u015D": "s",
                "\u1E61": "s",
                "\u0161": "s",
                "\u1E67": "s",
                "\u1E63": "s",
                "\u1E69": "s",
                "\u0219": "s",
                "\u015F": "s",
                "\u023F": "s",
                "\uA7A9": "s",
                "\uA785": "s",
                "\u1E9B": "s",
                "\u24E3": "t",
                "\uFF54": "t",
                "\u1E6B": "t",
                "\u1E97": "t",
                "\u0165": "t",
                "\u1E6D": "t",
                "\u021B": "t",
                "\u0163": "t",
                "\u1E71": "t",
                "\u1E6F": "t",
                "\u0167": "t",
                "\u01AD": "t",
                "\u0288": "t",
                "\u2C66": "t",
                "\uA787": "t",
                "\uA729": "tz",
                "\u24E4": "u",
                "\uFF55": "u",
                "\u00F9": "u",
                "\u00FA": "u",
                "\u00FB": "u",
                "\u0169": "u",
                "\u1E79": "u",
                "\u016B": "u",
                "\u1E7B": "u",
                "\u016D": "u",
                "\u00FC": "u",
                "\u01DC": "u",
                "\u01D8": "u",
                "\u01D6": "u",
                "\u01DA": "u",
                "\u1EE7": "u",
                "\u016F": "u",
                "\u0171": "u",
                "\u01D4": "u",
                "\u0215": "u",
                "\u0217": "u",
                "\u01B0": "u",
                "\u1EEB": "u",
                "\u1EE9": "u",
                "\u1EEF": "u",
                "\u1EED": "u",
                "\u1EF1": "u",
                "\u1EE5": "u",
                "\u1E73": "u",
                "\u0173": "u",
                "\u1E77": "u",
                "\u1E75": "u",
                "\u0289": "u",
                "\u24E5": "v",
                "\uFF56": "v",
                "\u1E7D": "v",
                "\u1E7F": "v",
                "\u028B": "v",
                "\uA75F": "v",
                "\u028C": "v",
                "\uA761": "vy",
                "\u24E6": "w",
                "\uFF57": "w",
                "\u1E81": "w",
                "\u1E83": "w",
                "\u0175": "w",
                "\u1E87": "w",
                "\u1E85": "w",
                "\u1E98": "w",
                "\u1E89": "w",
                "\u2C73": "w",
                "\u24E7": "x",
                "\uFF58": "x",
                "\u1E8B": "x",
                "\u1E8D": "x",
                "\u24E8": "y",
                "\uFF59": "y",
                "\u1EF3": "y",
                "\u00FD": "y",
                "\u0177": "y",
                "\u1EF9": "y",
                "\u0233": "y",
                "\u1E8F": "y",
                "\u00FF": "y",
                "\u1EF7": "y",
                "\u1E99": "y",
                "\u1EF5": "y",
                "\u01B4": "y",
                "\u024F": "y",
                "\u1EFF": "y",
                "\u24E9": "z",
                "\uFF5A": "z",
                "\u017A": "z",
                "\u1E91": "z",
                "\u017C": "z",
                "\u017E": "z",
                "\u1E93": "z",
                "\u1E95": "z",
                "\u01B6": "z",
                "\u0225": "z",
                "\u0240": "z",
                "\u2C6C": "z",
                "\uA763": "z",
                "\u0386": "\u0391",
                "\u0388": "\u0395",
                "\u0389": "\u0397",
                "\u038A": "\u0399",
                "\u03AA": "\u0399",
                "\u038C": "\u039F",
                "\u038E": "\u03A5",
                "\u03AB": "\u03A5",
                "\u038F": "\u03A9",
                "\u03AC": "\u03B1",
                "\u03AD": "\u03B5",
                "\u03AE": "\u03B7",
                "\u03AF": "\u03B9",
                "\u03CA": "\u03B9",
                "\u0390": "\u03B9",
                "\u03CC": "\u03BF",
                "\u03CD": "\u03C5",
                "\u03CB": "\u03C5",
                "\u03B0": "\u03C5",
                "\u03C9": "\u03C9",
                "\u03C2": "\u03C3"
            };
        $document = $(document);
        nextUid = (function() {
            var counter = 1;
            return function() {
                return counter++;
            };
        }());
    
        function reinsertElement(element) {
            var placeholder = $(document.createTextNode(''));
            element.before(placeholder);
            placeholder.before(element);
            placeholder.remove();
        }
    
        function stripDiacritics(str) {
            function match(a) {
                return DIACRITICS[a] || a;
            }
            return str.replace(/[^\u0000-\u007E]/g, match);
        }
    
        function indexOf(value, array) {
            var i = 0,
                l = array.length;
            for (; i < l; i = i + 1) {
                if (equal(value, array[i])) return i;
            }
            return -1;
        }
    
        function measureScrollbar() {
            var $template = $(MEASURE_SCROLLBAR_TEMPLATE);
            $template.appendTo('body');
            var dim = {
                width: $template.width() - $template[0].clientWidth,
                height: $template.height() - $template[0].clientHeight
            };
            $template.remove();
            return dim;
        }
    
        function equal(a, b) {
            if (a === b) return true;
            if (a === undefined || b === undefined) return false;
            if (a === null || b === null) return false;
            if (a.constructor === String) return a + '' === b + '';
            if (b.constructor === String) return b + '' === a + '';
            return false;
        }
    
        function splitVal(string, separator) {
            var val, i, l;
            if (string === null || string.length < 1) return [];
            val = string.split(separator);
            for (i = 0, l = val.length; i < l; i = i + 1) val[i] = $.trim(val[i]);
            return val;
        }
    
        function getSideBorderPadding(element) {
            return element.outerWidth(false) - element.width();
        }
    
        function installKeyUpChangeEvent(element) {
            var key = "keyup-change-value";
            element.on("keydown", function() {
                if ($.data(element, key) === undefined) {
                    $.data(element, key, element.val());
                }
            });
            element.on("keyup", function() {
                var val = $.data(element, key);
                if (val !== undefined && element.val() !== val) {
                    $.removeData(element, key);
                    element.trigger("keyup-change");
                }
            });
        }
    
        function installFilteredMouseMove(element) {
            element.on("mousemove", function(e) {
                var lastpos = lastMousePosition;
                if (lastpos === undefined || lastpos.x !== e.pageX || lastpos.y !== e.pageY) {
                    $(e.target).trigger("mousemove-filtered", e);
                }
            });
        }
    
        function debounce(quietMillis, fn, ctx) {
            ctx = ctx || undefined;
            var timeout;
            return function() {
                var args = arguments;
                window.clearTimeout(timeout);
                timeout = window.setTimeout(function() {
                    fn.apply(ctx, args);
                }, quietMillis);
            };
        }
    
        function installDebouncedScroll(threshold, element) {
            var notify = debounce(threshold, function(e) {
                element.trigger("scroll-debounced", e);
            });
            element.on("scroll", function(e) {
                if (indexOf(e.target, element.get()) >= 0) notify(e);
            });
        }
    
        function focus($el) {
            if ($el[0] === document.activeElement) return;
            window.setTimeout(function() {
                var el = $el[0],
                    pos = $el.val().length,
                    range;
                $el.focus();
                var isVisible = (el.offsetWidth > 0 || el.offsetHeight > 0);
                if (isVisible && el === document.activeElement) {
                    if (el.setSelectionRange) {
                        el.setSelectionRange(pos, pos);
                    } else if (el.createTextRange) {
                        range = el.createTextRange();
                        range.collapse(false);
                        range.select();
                    }
                }
            }, 0);
        }
    
        function getCursorInfo(el) {
            el = $(el)[0];
            var offset = 0;
            var length = 0;
            if ('selectionStart' in el) {
                offset = el.selectionStart;
                length = el.selectionEnd - offset;
            } else if ('selection' in document) {
                el.focus();
                var sel = document.selection.createRange();
                length = document.selection.createRange().text.length;
                sel.moveStart('character', -el.value.length);
                offset = sel.text.length - length;
            }
            return {
                offset: offset,
                length: length
            };
        }
    
        function killEvent(event) {
            event.preventDefault();
            event.stopPropagation();
        }
    
        function killEventImmediately(event) {
            event.preventDefault();
            event.stopImmediatePropagation();
        }
    
        function measureTextWidth(e) {
            if (!sizer) {
                var style = e[0].currentStyle || window.getComputedStyle(e[0], null);
                sizer = $(document.createElement("div")).css({
                    position: "absolute",
                    left: "-10000px",
                    top: "-10000px",
                    display: "none",
                    fontSize: style.fontSize,
                    fontFamily: style.fontFamily,
                    fontStyle: style.fontStyle,
                    fontWeight: style.fontWeight,
                    letterSpacing: style.letterSpacing,
                    textTransform: style.textTransform,
                    whiteSpace: "nowrap"
                });
                sizer.attr("class", "select2-sizer");
                $("body").append(sizer);
            }
            sizer.text(e.val());
            return sizer.width();
        }
    
        function syncCssClasses(dest, src, adapter) {
            var classes, replacements = [],
                adapted;
            classes = $.trim(dest.attr("class"));
            if (classes) {
                classes = '' + classes;
                $(classes.split(/\s+/)).each2(function() {
                    if (this.indexOf("select2-") === 0) {
                        replacements.push(this);
                    }
                });
            }
            classes = $.trim(src.attr("class"));
            if (classes) {
                classes = '' + classes;
                $(classes.split(/\s+/)).each2(function() {
                    if (this.indexOf("select2-") !== 0) {
                        adapted = adapter(this);
                        if (adapted) {
                            replacements.push(adapted);
                        }
                    }
                });
            }
            dest.attr("class", replacements.join(" "));
        }
    
        function markMatch(text, term, markup, escapeMarkup) {
            var match = stripDiacritics(text.toUpperCase()).indexOf(stripDiacritics(term.toUpperCase())),
                tl = term.length;
            if (match < 0) {
                markup.push(escapeMarkup(text));
                return;
            }
            markup.push(escapeMarkup(text.substring(0, match)));
            markup.push("<span class='select2-match'>");
            markup.push(escapeMarkup(text.substring(match, match + tl)));
            markup.push("</span>");
            markup.push(escapeMarkup(text.substring(match + tl, text.length)));
        }
    
        function defaultEscapeMarkup(markup) {
            var replace_map = {
                '\\': '&#92;',
                '&': '&amp;',
                '<': '&lt;',
                '>': '&gt;',
                '"': '&quot;',
                "'": '&#39;',
                "/": '&#47;'
            };
            return String(markup).replace(/[&<>"'\/\\]/g, function(match) {
                return replace_map[match];
            });
        }
    
        function ajax(options) {
            var timeout,
                handler = null,
                quietMillis = options.quietMillis || 100,
                ajaxUrl = options.url,
                self = this;
            return function(query) {
                window.clearTimeout(timeout);
                timeout = window.setTimeout(function() {
                    var data = options.data,
                        url = ajaxUrl,
                        transport = options.transport || $.fn.select2.ajaxDefaults.transport,
                        deprecated = {
                            type: options.type || 'GET',
                            cache: options.cache || false,
                            jsonpCallback: options.jsonpCallback || undefined,
                            dataType: options.dataType || "json"
                        },
                        params = $.extend({}, $.fn.select2.ajaxDefaults.params, deprecated);
                    data = data ? data.call(self, query.term, query.page, query.context) : null;
                    url = (typeof url === 'function') ? url.call(self, query.term, query.page, query.context) : url;
                    if (handler && typeof handler.abort === "function") {
                        handler.abort();
                    }
                    if (options.params) {
                        if ($.isFunction(options.params)) {
                            $.extend(params, options.params.call(self));
                        } else {
                            $.extend(params, options.params);
                        }
                    }
                    $.extend(params, {
                        url: url,
                        dataType: options.dataType,
                        data: data,
                        success: function(data) {
                            var results = options.results(data, query.page, query);
                            query.callback(results);
                        },
                        error: function(jqXHR, textStatus, errorThrown) {
                            var results = {
                                hasError: true,
                                jqXHR: jqXHR,
                                textStatus: textStatus,
                                errorThrown: errorThrown,
                            };
                            query.callback(results);
                        }
                    });
                    handler = transport.call(self, params);
                }, quietMillis);
            };
        }
    
        function local(options) {
            var data = options,
                dataText,
                tmp,
                text = function(item) {
                    return "" + item.text;
                };
            if ($.isArray(data)) {
                tmp = data;
                data = {
                    results: tmp
                };
            }
            if ($.isFunction(data) === false) {
                tmp = data;
                data = function() {
                    return tmp;
                };
            }
            var dataItem = data();
            if (dataItem.text) {
                text = dataItem.text;
                if (!$.isFunction(text)) {
                    dataText = dataItem.text;
                    text = function(item) {
                        return item[dataText];
                    };
                }
            }
            return function(query) {
                var t = query.term,
                    filtered = {
                        results: []
                    },
                    process;
                if (t === "") {
                    query.callback(data());
                    return;
                }
                process = function(datum, collection) {
                    var group, attr;
                    datum = datum[0];
                    if (datum.children) {
                        group = {};
                        for (attr in datum) {
                            if (datum.hasOwnProperty(attr)) group[attr] = datum[attr];
                        }
                        group.children = [];
                        $(datum.children).each2(function(i, childDatum) {
                            process(childDatum, group.children);
                        });
                        if (group.children.length || query.matcher(t, text(group), datum)) {
                            collection.push(group);
                        }
                    } else {
                        if (query.matcher(t, text(datum), datum)) {
                            collection.push(datum);
                        }
                    }
                };
                $(data().results).each2(function(i, datum) {
                    process(datum, filtered.results);
                });
                query.callback(filtered);
            };
        }
    
        function tags(data) {
            var isFunc = $.isFunction(data);
            return function(query) {
                var t = query.term,
                    filtered = {
                        results: []
                    };
                var result = isFunc ? data(query) : data;
                if ($.isArray(result)) {
                    $(result).each(function() {
                        var isObject = this.text !== undefined,
                            text = isObject ? this.text : this;
                        if (t === "" || query.matcher(t, text)) {
                            filtered.results.push(isObject ? this : {
                                id: this,
                                text: this
                            });
                        }
                    });
                    query.callback(filtered);
                }
            };
        }
    
        function checkFormatter(formatter, formatterName) {
            if ($.isFunction(formatter)) return true;
            if (!formatter) return false;
            if (typeof(formatter) === 'string') return true;
            throw new Error(formatterName + " must be a string, function, or falsy value");
        }
    
        function evaluate(val, context) {
            if ($.isFunction(val)) {
                var args = Array.prototype.slice.call(arguments, 2);
                return val.apply(context, args);
            }
            return val;
        }
    
        function countResults(results) {
            var count = 0;
            $.each(results, function(i, item) {
                if (item.children) {
                    count += countResults(item.children);
                } else {
                    count++;
                }
            });
            return count;
        }
    
        function defaultTokenizer(input, selection, selectCallback, opts) {
            var original = input,
                dupe = false,
                token,
                index,
                i, l,
                separator;
            if (!opts.createSearchChoice || !opts.tokenSeparators || opts.tokenSeparators.length < 1) return undefined;
            while (true) {
                index = -1;
                for (i = 0, l = opts.tokenSeparators.length; i < l; i++) {
                    separator = opts.tokenSeparators[i];
                    index = input.indexOf(separator);
                    if (index >= 0) break;
                }
                if (index < 0) break;
                token = input.substring(0, index);
                input = input.substring(index + separator.length);
                if (token.length > 0) {
                    token = opts.createSearchChoice.call(this, token, selection);
                    if (token !== undefined && token !== null && opts.id(token) !== undefined && opts.id(token) !== null) {
                        dupe = false;
                        for (i = 0, l = selection.length; i < l; i++) {
                            if (equal(opts.id(token), opts.id(selection[i]))) {
                                dupe = true;
                                break;
                            }
                        }
                        if (!dupe) selectCallback(token);
                    }
                }
            }
            if (original !== input) return input;
        }
    
        function cleanupJQueryElements() {
            var self = this;
            $.each(arguments, function(i, element) {
                self[element].remove();
                self[element] = null;
            });
        }
    
        function clazz(SuperClass, methods) {
            var constructor = function() {};
            constructor.prototype = new SuperClass;
            constructor.prototype.constructor = constructor;
            constructor.prototype.parent = SuperClass.prototype;
            constructor.prototype = $.extend(constructor.prototype, methods);
            return constructor;
        }
        AbstractSelect2 = clazz(Object, {
            bind: function(func) {
                var self = this;
                return function() {
                    func.apply(self, arguments);
                };
            },
            init: function(opts) {
                var results, search, resultsSelector = ".select2-results";
                this.opts = opts = this.prepareOpts(opts);
                this.id = opts.id;
                if (opts.element.data("select2") !== undefined &&
                    opts.element.data("select2") !== null) {
                    opts.element.data("select2").destroy();
                }
                this.container = this.createContainer();
                this.liveRegion = $("<span>", {
                        role: "status",
                        "aria-live": "polite"
                    })
                    .addClass("select2-hidden-accessible")
                    .appendTo(document.body);
                this.containerId = "s2id_" + (opts.element.attr("id") || "autogen" + nextUid());
                this.containerEventName = this.containerId
                    .replace(/([.])/g, '_')
                    .replace(/([;&,\-\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1');
                this.container.attr("id", this.containerId);
                this.container.attr("title", opts.element.attr("title"));
                this.body = $("body");
                syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
                this.container.attr("style", opts.element.attr("style"));
                this.container.css(evaluate(opts.containerCss, this.opts.element));
                this.container.addClass(evaluate(opts.containerCssClass, this.opts.element));
                this.elementTabIndex = this.opts.element.attr("tabindex");
                this.opts.element
                    .data("select2", this)
                    .attr("tabindex", "-1")
                    .before(this.container)
                    .on("click.select2", killEvent);
                this.container.data("select2", this);
                this.dropdown = this.container.find(".select2-drop");
                syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass);
                this.dropdown.addClass(evaluate(opts.dropdownCssClass, this.opts.element));
                this.dropdown.data("select2", this);
                this.dropdown.on("click", killEvent);
                this.results = results = this.container.find(resultsSelector);
                this.search = search = this.container.find("input.select2-input");
                this.queryCount = 0;
                this.resultsPage = 0;
                this.context = null;
                this.initContainer();
                this.container.on("click", killEvent);
                installFilteredMouseMove(this.results);
                this.dropdown.on("mousemove-filtered", resultsSelector, this.bind(this.highlightUnderEvent));
                this.dropdown.on("touchstart touchmove touchend", resultsSelector, this.bind(function(event) {
                    this._touchEvent = true;
                    this.highlightUnderEvent(event);
                }));
                this.dropdown.on("touchmove", resultsSelector, this.bind(this.touchMoved));
                this.dropdown.on("touchstart touchend", resultsSelector, this.bind(this.clearTouchMoved));
                this.dropdown.on('click', this.bind(function(event) {
                    if (this._touchEvent) {
                        this._touchEvent = false;
                        this.selectHighlighted();
                    }
                }));
                installDebouncedScroll(80, this.results);
                this.dropdown.on("scroll-debounced", resultsSelector, this.bind(this.loadMoreIfNeeded));
                $(this.container).on("change", ".select2-input", function(e) {
                    e.stopPropagation();
                });
                $(this.dropdown).on("change", ".select2-input", function(e) {
                    e.stopPropagation();
                });
                if ($.fn.mousewheel) {
                    results.mousewheel(function(e, delta, deltaX, deltaY) {
                        var top = results.scrollTop();
                        if (deltaY > 0 && top - deltaY <= 0) {
                            results.scrollTop(0);
                            killEvent(e);
                        } else if (deltaY < 0 && results.get(0).scrollHeight - results.scrollTop() + deltaY <= results.height()) {
                            results.scrollTop(results.get(0).scrollHeight - results.height());
                            killEvent(e);
                        }
                    });
                }
                installKeyUpChangeEvent(search);
                search.on("keyup-change input paste", this.bind(this.updateResults));
                search.on("focus", function() {
                    search.addClass("select2-focused");
                });
                search.on("blur", function() {
                    search.removeClass("select2-focused");
                });
                this.dropdown.on("mouseup", resultsSelector, this.bind(function(e) {
                    if ($(e.target).closest(".select2-result-selectable").length > 0) {
                        this.highlightUnderEvent(e);
                        this.selectHighlighted(e);
                    }
                }));
                this.dropdown.on("click mouseup mousedown touchstart touchend focusin", function(e) {
                    e.stopPropagation();
                });
                this.nextSearchTerm = undefined;
                if ($.isFunction(this.opts.initSelection)) {
                    this.initSelection();
                    this.monitorSource();
                }
                if (opts.maximumInputLength !== null) {
                    this.search.attr("maxlength", opts.maximumInputLength);
                }
                var disabled = opts.element.prop("disabled");
                if (disabled === undefined) disabled = false;
                this.enable(!disabled);
                var readonly = opts.element.prop("readonly");
                if (readonly === undefined) readonly = false;
                this.readonly(readonly);
                scrollBarDimensions = scrollBarDimensions || measureScrollbar();
                this.autofocus = opts.element.prop("autofocus");
                opts.element.prop("autofocus", false);
                if (this.autofocus) this.focus();
                this.search.attr("placeholder", opts.searchInputPlaceholder);
            },
            destroy: function() {
                var element = this.opts.element,
                    select2 = element.data("select2"),
                    self = this;
                this.close();
                if (element.length && element[0].detachEvent) {
                    element.each(function() {
                        this.detachEvent("onpropertychange", self._sync);
                    });
                }
                if (this.propertyObserver) {
                    this.propertyObserver.disconnect();
                    this.propertyObserver = null;
                }
                this._sync = null;
                if (select2 !== undefined) {
                    select2.container.remove();
                    select2.liveRegion.remove();
                    select2.dropdown.remove();
                    element
                        .removeClass("select2-offscreen")
                        .removeData("select2")
                        .off(".select2")
                        .prop("autofocus", this.autofocus || false);
                    if (this.elementTabIndex) {
                        element.attr({
                            tabindex: this.elementTabIndex
                        });
                    } else {
                        element.removeAttr("tabindex");
                    }
                    element.show();
                }
                cleanupJQueryElements.call(this,
                    "container",
                    "liveRegion",
                    "dropdown",
                    "results",
                    "search"
                );
            },
            optionToData: function(element) {
                if (element.is("option")) {
                    return {
                        id: element.prop("value"),
                        text: element.text(),
                        element: element.get(),
                        css: element.attr("class"),
                        disabled: element.prop("disabled"),
                        locked: equal(element.attr("locked"), "locked") || equal(element.data("locked"), true)
                    };
                } else if (element.is("optgroup")) {
                    return {
                        text: element.attr("label"),
                        children: [],
                        element: element.get(),
                        css: element.attr("class")
                    };
                }
            },
            prepareOpts: function(opts) {
                var element, select, idKey, ajaxUrl, self = this;
                element = opts.element;
                if (element.get(0).tagName.toLowerCase() === "select") {
                    this.select = select = opts.element;
                }
                if (select) {
                    $.each(["id", "multiple", "ajax", "query", "createSearchChoice", "initSelection", "data", "tags"], function() {
                        if (this in opts) {
                            throw new Error("Option '" + this + "' is not allowed for Select2 when attached to a <select> element.");
                        }
                    });
                }
                opts = $.extend({}, {
                    populateResults: function(container, results, query) {
                        var populate, id = this.opts.id,
                            liveRegion = this.liveRegion;
                        populate = function(results, container, depth) {
                            var i, l, result, selectable, disabled, compound, node, label, innerContainer, formatted;
                            results = opts.sortResults(results, container, query);
                            var nodes = [];
                            for (i = 0, l = results.length; i < l; i = i + 1) {
                                result = results[i];
                                disabled = (result.disabled === true);
                                selectable = (!disabled) && (id(result) !== undefined);
                                compound = result.children && result.children.length > 0;
                                node = $("<li></li>");
                                node.addClass("select2-results-dept-" + depth);
                                node.addClass("select2-result");
                                node.addClass(selectable ? "select2-result-selectable" : "select2-result-unselectable");
                                if (disabled) {
                                    node.addClass("select2-disabled");
                                }
                                if (compound) {
                                    node.addClass("select2-result-with-children");
                                }
                                node.addClass(self.opts.formatResultCssClass(result));
                                node.attr("role", "presentation");
                                label = $(document.createElement("div"));
                                label.addClass("select2-result-label");
                                label.attr("id", "select2-result-label-" + nextUid());
                                label.attr("role", "option");
                                formatted = opts.formatResult(result, label, query, self.opts.escapeMarkup);
                                if (formatted !== undefined) {
                                    label.html(formatted);
                                    node.append(label);
                                }
                                if (compound) {
                                    innerContainer = $("<ul></ul>");
                                    innerContainer.addClass("select2-result-sub");
                                    populate(result.children, innerContainer, depth + 1);
                                    node.append(innerContainer);
                                }
                                node.data("select2-data", result);
                                nodes.push(node[0]);
                            }
                            container.append(nodes);
                            liveRegion.text(opts.formatMatches(results.length));
                        };
                        populate(results, container, 0);
                    }
                }, $.fn.select2.defaults, opts);
                if (typeof(opts.id) !== "function") {
                    idKey = opts.id;
                    opts.id = function(e) {
                        return e[idKey];
                    };
                }
                if ($.isArray(opts.element.data("select2Tags"))) {
                    if ("tags" in opts) {
                        throw "tags specified as both an attribute 'data-select2-tags' and in options of Select2 " + opts.element.attr("id");
                    }
                    opts.tags = opts.element.data("select2Tags");
                }
                if (select) {
                    opts.query = this.bind(function(query) {
                        var data = {
                                results: [],
                                more: false
                            },
                            term = query.term,
                            children, placeholderOption, process;
                        process = function(element, collection) {
                            var group;
                            if (element.is("option")) {
                                if (query.matcher(term, element.text(), element)) {
                                    collection.push(self.optionToData(element));
                                }
                            } else if (element.is("optgroup")) {
                                group = self.optionToData(element);
                                element.children().each2(function(i, elm) {
                                    process(elm, group.children);
                                });
                                if (group.children.length > 0) {
                                    collection.push(group);
                                }
                            }
                        };
                        children = element.children();
                        if (this.getPlaceholder() !== undefined && children.length > 0) {
                            placeholderOption = this.getPlaceholderOption();
                            if (placeholderOption) {
                                children = children.not(placeholderOption);
                            }
                        }
                        children.each2(function(i, elm) {
                            process(elm, data.results);
                        });
                        query.callback(data);
                    });
                    opts.id = function(e) {
                        return e.id;
                    };
                } else {
                    if (!("query" in opts)) {
                        if ("ajax" in opts) {
                            ajaxUrl = opts.element.data("ajax-url");
                            if (ajaxUrl && ajaxUrl.length > 0) {
                                opts.ajax.url = ajaxUrl;
                            }
                            opts.query = ajax.call(opts.element, opts.ajax);
                        } else if ("data" in opts) {
                            opts.query = local(opts.data);
                        } else if ("tags" in opts) {
                            opts.query = tags(opts.tags);
                            if (opts.createSearchChoice === undefined) {
                                opts.createSearchChoice = function(term) {
                                    return {
                                        id: $.trim(term),
                                        text: $.trim(term)
                                    };
                                };
                            }
                            if (opts.initSelection === undefined) {
                                opts.initSelection = function(element, callback) {
                                    var data = [];
                                    $(splitVal(element.val(), opts.separator)).each(function() {
                                        var obj = {
                                                id: this,
                                                text: this
                                            },
                                            tags = opts.tags;
                                        if ($.isFunction(tags)) tags = tags();
                                        $(tags).each(function() {
                                            if (equal(this.id, obj.id)) {
                                                obj = this;
                                                return false;
                                            }
                                        });
                                        data.push(obj);
                                    });
                                    callback(data);
                                };
                            }
                        }
                    }
                }
                if (typeof(opts.query) !== "function") {
                    throw "query function not defined for Select2 " + opts.element.attr("id");
                }
                if (opts.createSearchChoicePosition === 'top') {
                    opts.createSearchChoicePosition = function(list, item) {
                        list.unshift(item);
                    };
                } else if (opts.createSearchChoicePosition === 'bottom') {
                    opts.createSearchChoicePosition = function(list, item) {
                        list.push(item);
                    };
                } else if (typeof(opts.createSearchChoicePosition) !== "function") {
                    throw "invalid createSearchChoicePosition option must be 'top', 'bottom' or a custom function";
                }
                return opts;
            },
            monitorSource: function() {
                var el = this.opts.element,
                    observer, self = this;
                el.on("change.select2", this.bind(function(e) {
                    if (this.opts.element.data("select2-change-triggered") !== true) {
                        this.initSelection();
                    }
                }));
                this._sync = this.bind(function() {
                    var disabled = el.prop("disabled");
                    if (disabled === undefined) disabled = false;
                    this.enable(!disabled);
                    var readonly = el.prop("readonly");
                    if (readonly === undefined) readonly = false;
                    this.readonly(readonly);
                    syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
                    this.container.addClass(evaluate(this.opts.containerCssClass, this.opts.element));
                    syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass);
                    this.dropdown.addClass(evaluate(this.opts.dropdownCssClass, this.opts.element));
                });
                if (el.length && el[0].attachEvent) {
                    el.each(function() {
                        this.attachEvent("onpropertychange", self._sync);
                    });
                }
                observer = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
                if (observer !== undefined) {
                    if (this.propertyObserver) {
                        delete this.propertyObserver;
                        this.propertyObserver = null;
                    }
                    this.propertyObserver = new observer(function(mutations) {
                        $.each(mutations, self._sync);
                    });
                    this.propertyObserver.observe(el.get(0), {
                        attributes: true,
                        subtree: false
                    });
                }
            },
            triggerSelect: function(data) {
                var evt = $.Event("select2-selecting", {
                    val: this.id(data),
                    object: data,
                    choice: data
                });
                this.opts.element.trigger(evt);
                return !evt.isDefaultPrevented();
            },
            triggerChange: function(details) {
                details = details || {};
                details = $.extend({}, details, {
                    type: "change",
                    val: this.val()
                });
                this.opts.element.data("select2-change-triggered", true);
                this.opts.element.trigger(details);
                this.opts.element.data("select2-change-triggered", false);
                this.opts.element.click();
                if (this.opts.blurOnChange)
                    this.opts.element.blur();
            },
            isInterfaceEnabled: function() {
                return this.enabledInterface === true;
            },
            enableInterface: function() {
                var enabled = this._enabled && !this._readonly,
                    disabled = !enabled;
                if (enabled === this.enabledInterface) return false;
                this.container.toggleClass("select2-container-disabled", disabled);
                this.close();
                this.enabledInterface = enabled;
                return true;
            },
            enable: function(enabled) {
                if (enabled === undefined) enabled = true;
                if (this._enabled === enabled) return;
                this._enabled = enabled;
                this.opts.element.prop("disabled", !enabled);
                this.enableInterface();
            },
            disable: function() {
                this.enable(false);
            },
            readonly: function(enabled) {
                if (enabled === undefined) enabled = false;
                if (this._readonly === enabled) return;
                this._readonly = enabled;
                this.opts.element.prop("readonly", enabled);
                this.enableInterface();
            },
            opened: function() {
                return (this.container) ? this.container.hasClass("select2-dropdown-open") : false;
            },
            positionDropdown: function() {
                var $dropdown = this.dropdown,
                    offset = this.container.offset(),
                    height = this.container.outerHeight(false),
                    width = this.container.outerWidth(false),
                    dropHeight = $dropdown.outerHeight(false),
                    $window = $(window),
                    windowWidth = $window.width(),
                    windowHeight = $window.height(),
                    viewPortRight = $window.scrollLeft() + windowWidth,
                    viewportBottom = $window.scrollTop() + windowHeight,
                    dropTop = offset.top + height,
                    dropLeft = offset.left,
                    enoughRoomBelow = dropTop + dropHeight <= viewportBottom,
                    enoughRoomAbove = (offset.top - dropHeight) >= $window.scrollTop(),
                    dropWidth = $dropdown.outerWidth(false),
                    enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight,
                    aboveNow = $dropdown.hasClass("select2-drop-above"),
                    bodyOffset,
                    above,
                    changeDirection,
                    css,
                    resultsListNode;
                if (aboveNow) {
                    above = true;
                    if (!enoughRoomAbove && enoughRoomBelow) {
                        changeDirection = true;
                        above = false;
                    }
                } else {
                    above = false;
                    if (!enoughRoomBelow && enoughRoomAbove) {
                        changeDirection = true;
                        above = true;
                    }
                }
                if (changeDirection) {
                    $dropdown.hide();
                    offset = this.container.offset();
                    height = this.container.outerHeight(false);
                    width = this.container.outerWidth(false);
                    dropHeight = $dropdown.outerHeight(false);
                    viewPortRight = $window.scrollLeft() + windowWidth;
                    viewportBottom = $window.scrollTop() + windowHeight;
                    dropTop = offset.top + height;
                    dropLeft = offset.left;
                    dropWidth = $dropdown.outerWidth(false);
                    enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight;
                    $dropdown.show();
                    this.focusSearch();
                }
                if (this.opts.dropdownAutoWidth) {
                    resultsListNode = $('.select2-results', $dropdown)[0];
                    $dropdown.addClass('select2-drop-auto-width');
                    $dropdown.css('width', '');
                    dropWidth = $dropdown.outerWidth(false) + (resultsListNode.scrollHeight === resultsListNode.clientHeight ? 0 : scrollBarDimensions.width);
                    dropWidth > width ? width = dropWidth : dropWidth = width;
                    dropHeight = $dropdown.outerHeight(false);
                    enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight;
                } else {
                    this.container.removeClass('select2-drop-auto-width');
                }
                if (this.body.css('position') !== 'static') {
                    bodyOffset = this.body.offset();
                    dropTop -= bodyOffset.top;
                    dropLeft -= bodyOffset.left;
                }
                if (!enoughRoomOnRight) {
                    dropLeft = offset.left + this.container.outerWidth(false) - dropWidth;
                }
                css = {
                    left: dropLeft,
                    width: width
                };
                if (above) {
                    css.top = offset.top - dropHeight;
                    css.bottom = 'auto';
                    this.container.addClass("select2-drop-above");
                    $dropdown.addClass("select2-drop-above");
                } else {
                    css.top = dropTop;
                    css.bottom = 'auto';
                    this.container.removeClass("select2-drop-above");
                    $dropdown.removeClass("select2-drop-above");
                }
                css = $.extend(css, evaluate(this.opts.dropdownCss, this.opts.element));
                $dropdown.css(css);
            },
            shouldOpen: function() {
                var event;
                if (this.opened()) return false;
                if (this._enabled === false || this._readonly === true) return false;
                event = $.Event("select2-opening");
                this.opts.element.trigger(event);
                return !event.isDefaultPrevented();
            },
            clearDropdownAlignmentPreference: function() {
                this.container.removeClass("select2-drop-above");
                this.dropdown.removeClass("select2-drop-above");
            },
            open: function() {
                if (!this.shouldOpen()) return false;
                this.opening();
                $document.on("mousemove.select2Event", function(e) {
                    lastMousePosition.x = e.pageX;
                    lastMousePosition.y = e.pageY;
                });
                return true;
            },
            opening: function() {
                var cid = this.containerEventName,
                    scroll = "scroll." + cid,
                    resize = "resize." + cid,
                    orient = "orientationchange." + cid,
                    mask;
                this.container.addClass("select2-dropdown-open").addClass("select2-container-active");
                this.clearDropdownAlignmentPreference();
                if (this.dropdown[0] !== this.body.children().last()[0]) {
                    this.dropdown.detach().appendTo(this.body);
                }
                mask = $("#select2-drop-mask");
                if (mask.length == 0) {
                    mask = $(document.createElement("div"));
                    mask.attr("id", "select2-drop-mask").attr("class", "select2-drop-mask");
                    mask.hide();
                    mask.appendTo(this.body);
                    mask.on("mousedown touchstart click", function(e) {
                        reinsertElement(mask);
                        var dropdown = $("#select2-drop"),
                            self;
                        if (dropdown.length > 0) {
                            self = dropdown.data("select2");
                            if (self.opts.selectOnBlur) {
                                self.selectHighlighted({
                                    noFocus: true
                                });
                            }
                            self.close();
                            e.preventDefault();
                            e.stopPropagation();
                        }
                    });
                }
                if (this.dropdown.prev()[0] !== mask[0]) {
                    this.dropdown.before(mask);
                }
                $("#select2-drop").removeAttr("id");
                this.dropdown.attr("id", "select2-drop");
                mask.show();
                this.positionDropdown();
                this.dropdown.show();
                this.positionDropdown();
                this.dropdown.addClass("select2-drop-active");
                var that = this;
                this.container.parents().add(window).each(function() {
                    $(this).on(resize + " " + scroll + " " + orient, function(e) {
                        if (that.opened()) that.positionDropdown();
                    });
                });
            },
            close: function() {
                if (!this.opened()) return;
                var cid = this.containerEventName,
                    scroll = "scroll." + cid,
                    resize = "resize." + cid,
                    orient = "orientationchange." + cid;
                this.container.parents().add(window).each(function() {
                    $(this).off(scroll).off(resize).off(orient);
                });
                this.clearDropdownAlignmentPreference();
                $("#select2-drop-mask").hide();
                this.dropdown.removeAttr("id");
                this.dropdown.hide();
                this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active");
                this.results.empty();
                $document.off("mousemove.select2Event");
                this.clearSearch();
                this.search.removeClass("select2-active");
                this.opts.element.trigger($.Event("select2-close"));
            },
            externalSearch: function(term) {
                this.open();
                this.search.val(term);
                this.updateResults(false);
            },
            clearSearch: function() {},
            getMaximumSelectionSize: function() {
                return evaluate(this.opts.maximumSelectionSize, this.opts.element);
            },
            ensureHighlightVisible: function() {
                var results = this.results,
                    children, index, child, hb, rb, y, more, topOffset;
                index = this.highlight();
                if (index < 0) return;
                if (index == 0) {
                    results.scrollTop(0);
                    return;
                }
                children = this.findHighlightableChoices().find('.select2-result-label');
                child = $(children[index]);
                topOffset = (child.offset() || {}).top || 0;
                hb = topOffset + child.outerHeight(true);
                if (index === children.length - 1) {
                    more = results.find("li.select2-more-results");
                    if (more.length > 0) {
                        hb = more.offset().top + more.outerHeight(true);
                    }
                }
                rb = results.offset().top + results.outerHeight(true);
                if (hb > rb) {
                    results.scrollTop(results.scrollTop() + (hb - rb));
                }
                y = topOffset - results.offset().top;
                if (y < 0 && child.css('display') != 'none') {
                    results.scrollTop(results.scrollTop() + y);
                }
            },
            findHighlightableChoices: function() {
                return this.results.find(".select2-result-selectable:not(.select2-disabled):not(.select2-selected)");
            },
            moveHighlight: function(delta) {
                var choices = this.findHighlightableChoices(),
                    index = this.highlight();
                while (index > -1 && index < choices.length) {
                    index += delta;
                    var choice = $(choices[index]);
                    if (choice.hasClass("select2-result-selectable") && !choice.hasClass("select2-disabled") && !choice.hasClass("select2-selected")) {
                        this.highlight(index);
                        break;
                    }
                }
            },
            highlight: function(index) {
                var choices = this.findHighlightableChoices(),
                    choice,
                    data;
                if (arguments.length === 0) {
                    return indexOf(choices.filter(".select2-highlighted")[0], choices.get());
                }
                if (index >= choices.length) index = choices.length - 1;
                if (index < 0) index = 0;
                this.removeHighlight();
                choice = $(choices[index]);
                choice.addClass("select2-highlighted");
                this.search.attr("aria-activedescendant", choice.find(".select2-result-label").attr("id"));
                this.ensureHighlightVisible();
                this.liveRegion.text(choice.text());
                data = choice.data("select2-data");
                if (data) {
                    this.opts.element.trigger({
                        type: "select2-highlight",
                        val: this.id(data),
                        choice: data
                    });
                }
            },
            removeHighlight: function() {
                this.results.find(".select2-highlighted").removeClass("select2-highlighted");
            },
            touchMoved: function() {
                this._touchMoved = true;
            },
            clearTouchMoved: function() {
                this._touchMoved = false;
            },
            countSelectableResults: function() {
                return this.findHighlightableChoices().length;
            },
            highlightUnderEvent: function(event) {
                var el = $(event.target).closest(".select2-result-selectable");
                if (el.length > 0 && !el.is(".select2-highlighted")) {
                    var choices = this.findHighlightableChoices();
                    this.highlight(choices.index(el));
                } else if (el.length == 0) {
                    this.removeHighlight();
                }
            },
            loadMoreIfNeeded: function() {
                var results = this.results,
                    more = results.find("li.select2-more-results"),
                    below,
                    page = this.resultsPage + 1,
                    self = this,
                    term = this.search.val(),
                    context = this.context;
                if (more.length === 0) return;
                below = more.offset().top - results.offset().top - results.height();
                if (below <= this.opts.loadMorePadding) {
                    more.addClass("select2-active");
                    this.opts.query({
                        element: this.opts.element,
                        term: term,
                        page: page,
                        context: context,
                        matcher: this.opts.matcher,
                        callback: this.bind(function(data) {
                            if (!self.opened()) return;
                            self.opts.populateResults.call(this, results, data.results, {
                                term: term,
                                page: page,
                                context: context
                            });
                            self.postprocessResults(data, false, false);
                            if (data.more === true) {
                                more.detach().appendTo(results).text(evaluate(self.opts.formatLoadMore, self.opts.element, page + 1));
                                window.setTimeout(function() {
                                    self.loadMoreIfNeeded();
                                }, 10);
                            } else {
                                more.remove();
                            }
                            self.positionDropdown();
                            self.resultsPage = page;
                            self.context = data.context;
                            this.opts.element.trigger({
                                type: "select2-loaded",
                                items: data
                            });
                        })
                    });
                }
            },
            tokenize: function() {},
            updateResults: function(initial) {
                var search = this.search,
                    results = this.results,
                    opts = this.opts,
                    data,
                    self = this,
                    input,
                    term = search.val(),
                    lastTerm = $.data(this.container, "select2-last-term"),
                    queryNumber;
                if (initial !== true && lastTerm && equal(term, lastTerm)) return;
                $.data(this.container, "select2-last-term", term);
                if (initial !== true && (this.showSearchInput === false || !this.opened())) {
                    return;
                }
    
                function postRender() {
                    search.removeClass("select2-active");
                    self.positionDropdown();
                    if (results.find('.select2-no-results,.select2-selection-limit,.select2-searching').length) {
                        self.liveRegion.text(results.text());
                    } else {
                        self.liveRegion.text(self.opts.formatMatches(results.find('.select2-result-selectable').length));
                    }
                }
    
                function render(html) {
                    results.html(html);
                    postRender();
                }
                queryNumber = ++this.queryCount;
                var maxSelSize = this.getMaximumSelectionSize();
                if (maxSelSize >= 1) {
                    data = this.data();
                    if ($.isArray(data) && data.length >= maxSelSize && checkFormatter(opts.formatSelectionTooBig, "formatSelectionTooBig")) {
                        render("<li class='select2-selection-limit'>" + evaluate(opts.formatSelectionTooBig, opts.element, maxSelSize) + "</li>");
                        return;
                    }
                }
                if (search.val().length < opts.minimumInputLength) {
                    if (checkFormatter(opts.formatInputTooShort, "formatInputTooShort")) {
                        render("<li class='select2-no-results'>" + evaluate(opts.formatInputTooShort, opts.element, search.val(), opts.minimumInputLength) + "</li>");
                    } else {
                        render("");
                    }
                    if (initial && this.showSearch) this.showSearch(true);
                    return;
                }
                if (opts.maximumInputLength && search.val().length > opts.maximumInputLength) {
                    if (checkFormatter(opts.formatInputTooLong, "formatInputTooLong")) {
                        render("<li class='select2-no-results'>" + evaluate(opts.formatInputTooLong, opts.element, search.val(), opts.maximumInputLength) + "</li>");
                    } else {
                        render("");
                    }
                    return;
                }
                if (opts.formatSearching && this.findHighlightableChoices().length === 0) {
                    render("<li class='select2-searching'>" + evaluate(opts.formatSearching, opts.element) + "</li>");
                }
                search.addClass("select2-active");
                this.removeHighlight();
                input = this.tokenize();
                if (input != undefined && input != null) {
                    search.val(input);
                }
                this.resultsPage = 1;
                opts.query({
                    element: opts.element,
                    term: search.val(),
                    page: this.resultsPage,
                    context: null,
                    matcher: opts.matcher,
                    callback: this.bind(function(data) {
                        var def;
                        if (queryNumber != this.queryCount) {
                            return;
                        }
                        if (!this.opened()) {
                            this.search.removeClass("select2-active");
                            return;
                        }
                        if (data.hasError !== undefined && checkFormatter(opts.formatAjaxError, "formatAjaxError")) {
                            render("<li class='select2-ajax-error'>" + evaluate(opts.formatAjaxError, opts.element, data.jqXHR, data.textStatus, data.errorThrown) + "</li>");
                            return;
                        }
                        this.context = (data.context === undefined) ? null : data.context;
                        if (this.opts.createSearchChoice && search.val() !== "") {
                            def = this.opts.createSearchChoice.call(self, search.val(), data.results);
                            if (def !== undefined && def !== null && self.id(def) !== undefined && self.id(def) !== null) {
                                if ($(data.results).filter(
                                        function() {
                                            return equal(self.id(this), self.id(def));
                                        }).length === 0) {
                                    this.opts.createSearchChoicePosition(data.results, def);
                                }
                            }
                        }
                        if (data.results.length === 0 && checkFormatter(opts.formatNoMatches, "formatNoMatches")) {
                            render("<li class='select2-no-results'>" + evaluate(opts.formatNoMatches, opts.element, search.val()) + "</li>");
                            return;
                        }
                        results.empty();
                        self.opts.populateResults.call(this, results, data.results, {
                            term: search.val(),
                            page: this.resultsPage,
                            context: null
                        });
                        if (data.more === true && checkFormatter(opts.formatLoadMore, "formatLoadMore")) {
                            results.append("<li class='select2-more-results'>" + opts.escapeMarkup(evaluate(opts.formatLoadMore, opts.element, this.resultsPage)) + "</li>");
                            window.setTimeout(function() {
                                self.loadMoreIfNeeded();
                            }, 10);
                        }
                        this.postprocessResults(data, initial);
                        postRender();
                        this.opts.element.trigger({
                            type: "select2-loaded",
                            items: data
                        });
                    })
                });
            },
            cancel: function() {
                this.close();
            },
            blur: function() {
                if (this.opts.selectOnBlur)
                    this.selectHighlighted({
                        noFocus: true
                    });
                this.close();
                this.container.removeClass("select2-container-active");
                if (this.search[0] === document.activeElement) {
                    this.search.blur();
                }
                this.clearSearch();
                this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
            },
            focusSearch: function() {
                focus(this.search);
            },
            selectHighlighted: function(options) {
                if (this._touchMoved) {
                    this.clearTouchMoved();
                    return;
                }
                var index = this.highlight(),
                    highlighted = this.results.find(".select2-highlighted"),
                    data = highlighted.closest('.select2-result').data("select2-data");
                if (data) {
                    this.highlight(index);
                    this.onSelect(data, options);
                } else if (options && options.noFocus) {
                    this.close();
                }
            },
            getPlaceholder: function() {
                var placeholderOption;
                return this.opts.element.attr("placeholder") ||
                    this.opts.element.attr("data-placeholder") ||
                    this.opts.element.data("placeholder") ||
                    this.opts.placeholder ||
                    ((placeholderOption = this.getPlaceholderOption()) !== undefined ? placeholderOption.text() : undefined);
            },
            getPlaceholderOption: function() {
                if (this.select) {
                    var firstOption = this.select.children('option').first();
                    if (this.opts.placeholderOption !== undefined) {
                        return (this.opts.placeholderOption === "first" && firstOption) ||
                            (typeof this.opts.placeholderOption === "function" && this.opts.placeholderOption(this.select));
                    } else if ($.trim(firstOption.text()) === "" && firstOption.val() === "") {
                        return firstOption;
                    }
                }
            },
            initContainerWidth: function() {
                function resolveContainerWidth() {
                    var style, attrs, matches, i, l, attr;
                    if (this.opts.width === "off") {
                        return null;
                    } else if (this.opts.width === "element") {
                        return this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px';
                    } else if (this.opts.width === "copy" || this.opts.width === "resolve") {
                        style = this.opts.element.attr('style');
                        if (style !== undefined) {
                            attrs = style.split(';');
                            for (i = 0, l = attrs.length; i < l; i = i + 1) {
                                attr = attrs[i].replace(/\s/g, '');
                                matches = attr.match(/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i);
                                if (matches !== null && matches.length >= 1)
                                    return matches[1];
                            }
                        }
                        if (this.opts.width === "resolve") {
                            style = this.opts.element.css('width');
                            if (style.indexOf("%") > 0) return style;
                            return (this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px');
                        }
                        return null;
                    } else if ($.isFunction(this.opts.width)) {
                        return this.opts.width();
                    } else {
                        return this.opts.width;
                    }
                };
                var width = resolveContainerWidth.call(this);
                if (width !== null) {
                    this.container.css("width", width);
                }
            }
        });
        SingleSelect2 = clazz(AbstractSelect2, {
            createContainer: function() {
                var container = $(document.createElement("div")).attr({
                    "class": "select2-container"
                }).html([
                    "<a href='javascript:void(0)' class='select2-choice' tabindex='-1'>",
                    "   <span class='select2-chosen'>&#160;</span><abbr class='select2-search-choice-close'></abbr>",
                    "   <span class='select2-arrow' role='presentation'><b role='presentation'></b></span>",
                    "</a>",
                    "<label for='' class='select2-offscreen'></label>",
                    "<input class='select2-focusser select2-offscreen' type='text' aria-haspopup='true' role='button' />",
                    "<div class='select2-drop select2-display-none'>",
                    "   <div class='select2-search'>",
                    "       <label for='' class='select2-offscreen'></label>",
                    "       <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input' role='combobox' aria-expanded='true'",
                    "       aria-autocomplete='list' />",
                    "   </div>",
                    "   <ul class='select2-results' role='listbox'>",
                    "   </ul>",
                    "</div>"
                ].join(""));
                return container;
            },
            enableInterface: function() {
                if (this.parent.enableInterface.apply(this, arguments)) {
                    this.focusser.prop("disabled", !this.isInterfaceEnabled());
                }
            },
            opening: function() {
                var el, range, len;
                if (this.opts.minimumResultsForSearch >= 0) {
                    this.showSearch(true);
                }
                this.parent.opening.apply(this, arguments);
                if (this.showSearchInput !== false) {
                    this.search.val(this.focusser.val());
                }
                if (this.opts.shouldFocusInput(this)) {
                    this.search.focus();
                    el = this.search.get(0);
                    if (el.createTextRange) {
                        range = el.createTextRange();
                        range.collapse(false);
                        range.select();
                    } else if (el.setSelectionRange) {
                        len = this.search.val().length;
                        el.setSelectionRange(len, len);
                    }
                }
                if (this.search.val() === "") {
                    if (this.nextSearchTerm != undefined) {
                        this.search.val(this.nextSearchTerm);
                        this.search.select();
                    }
                }
                this.focusser.prop("disabled", true).val("");
                this.updateResults(true);
                this.opts.element.trigger($.Event("select2-open"));
            },
            close: function() {
                if (!this.opened()) return;
                this.parent.close.apply(this, arguments);
                this.focusser.prop("disabled", false);
                if (this.opts.shouldFocusInput(this)) {
                    this.focusser.focus();
                }
            },
            focus: function() {
                if (this.opened()) {
                    this.close();
                } else {
                    this.focusser.prop("disabled", false);
                    if (this.opts.shouldFocusInput(this)) {
                        this.focusser.focus();
                    }
                }
            },
            isFocused: function() {
                return this.container.hasClass("select2-container-active");
            },
            cancel: function() {
                this.parent.cancel.apply(this, arguments);
                this.focusser.prop("disabled", false);
                if (this.opts.shouldFocusInput(this)) {
                    this.focusser.focus();
                }
            },
            destroy: function() {
                $("label[for='" + this.focusser.attr('id') + "']")
                    .attr('for', this.opts.element.attr("id"));
                this.parent.destroy.apply(this, arguments);
                cleanupJQueryElements.call(this,
                    "selection",
                    "focusser"
                );
            },
            initContainer: function() {
                var selection,
                    container = this.container,
                    dropdown = this.dropdown,
                    idSuffix = nextUid(),
                    elementLabel;
                if (this.opts.minimumResultsForSearch < 0) {
                    this.showSearch(false);
                } else {
                    this.showSearch(true);
                }
                this.selection = selection = container.find(".select2-choice");
                this.focusser = container.find(".select2-focusser");
                selection.find(".select2-chosen").attr("id", "select2-chosen-" + idSuffix);
                this.focusser.attr("aria-labelledby", "select2-chosen-" + idSuffix);
                this.results.attr("id", "select2-results-" + idSuffix);
                this.search.attr("aria-owns", "select2-results-" + idSuffix);
                this.focusser.attr("id", "s2id_autogen" + idSuffix);
                elementLabel = $("label[for='" + this.opts.element.attr("id") + "']");
                this.focusser.prev()
                    .text(elementLabel.text())
                    .attr('for', this.focusser.attr('id'));
                var originalTitle = this.opts.element.attr("title");
                this.opts.element.attr("title", (originalTitle || elementLabel.text()));
                this.focusser.attr("tabindex", this.elementTabIndex);
                this.search.attr("id", this.focusser.attr('id') + '_search');
                this.search.prev()
                    .text($("label[for='" + this.focusser.attr('id') + "']").text())
                    .attr('for', this.search.attr('id'));
                this.search.on("keydown", this.bind(function(e) {
                    if (!this.isInterfaceEnabled()) return;
                    if (229 == e.keyCode) return;
                    if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {
                        killEvent(e);
                        return;
                    }
                    switch (e.which) {
                        case KEY.UP:
                        case KEY.DOWN:
                            this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
                            killEvent(e);
                            return;
                        case KEY.ENTER:
                            this.selectHighlighted();
                            killEvent(e);
                            return;
                        case KEY.TAB:
                            this.selectHighlighted({
                                noFocus: true
                            });
                            return;
                        case KEY.ESC:
                            this.cancel(e);
                            killEvent(e);
                            return;
                    }
                }));
                this.search.on("blur", this.bind(function(e) {
                    if (document.activeElement === this.body.get(0)) {
                        window.setTimeout(this.bind(function() {
                            if (this.opened()) {
                                this.search.focus();
                            }
                        }), 0);
                    }
                }));
                this.focusser.on("keydown", this.bind(function(e) {
                    if (!this.isInterfaceEnabled()) return;
                    if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {
                        return;
                    }
                    if (this.opts.openOnEnter === false && e.which === KEY.ENTER) {
                        killEvent(e);
                        return;
                    }
                    if (e.which == KEY.DOWN || e.which == KEY.UP ||
                        (e.which == KEY.ENTER && this.opts.openOnEnter)) {
                        if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) return;
                        this.open();
                        killEvent(e);
                        return;
                    }
                    if (e.which == KEY.DELETE || e.which == KEY.BACKSPACE) {
                        if (this.opts.allowClear) {
                            this.clear();
                        }
                        killEvent(e);
                        return;
                    }
                }));
                installKeyUpChangeEvent(this.focusser);
                this.focusser.on("keyup-change input", this.bind(function(e) {
                    if (this.opts.minimumResultsForSearch >= 0) {
                        e.stopPropagation();
                        if (this.opened()) return;
                        this.open();
                    }
                }));
                selection.on("mousedown touchstart", "abbr", this.bind(function(e) {
                    if (!this.isInterfaceEnabled()) return;
                    this.clear();
                    killEventImmediately(e);
                    this.close();
                    this.selection.focus();
                }));
                selection.on("mousedown touchstart", this.bind(function(e) {
                    reinsertElement(selection);
                    if (!this.container.hasClass("select2-container-active")) {
                        this.opts.element.trigger($.Event("select2-focus"));
                    }
                    if (this.opened()) {
                        this.close();
                    } else if (this.isInterfaceEnabled()) {
                        this.open();
                    }
                    killEvent(e);
                }));
                dropdown.on("mousedown touchstart", this.bind(function() {
                    if (this.opts.shouldFocusInput(this)) {
                        this.search.focus();
                    }
                }));
                selection.on("focus", this.bind(function(e) {
                    killEvent(e);
                }));
                this.focusser.on("focus", this.bind(function() {
                    if (!this.container.hasClass("select2-container-active")) {
                        this.opts.element.trigger($.Event("select2-focus"));
                    }
                    this.container.addClass("select2-container-active");
                })).on("blur", this.bind(function() {
                    if (!this.opened()) {
                        this.container.removeClass("select2-container-active");
                        this.opts.element.trigger($.Event("select2-blur"));
                    }
                }));
                this.search.on("focus", this.bind(function() {
                    if (!this.container.hasClass("select2-container-active")) {
                        this.opts.element.trigger($.Event("select2-focus"));
                    }
                    this.container.addClass("select2-container-active");
                }));
                this.initContainerWidth();
                this.opts.element.addClass("select2-offscreen");
                this.setPlaceholder();
            },
            clear: function(triggerChange) {
                var data = this.selection.data("select2-data");
                if (data) {
                    var evt = $.Event("select2-clearing");
                    this.opts.element.trigger(evt);
                    if (evt.isDefaultPrevented()) {
                        return;
                    }
                    var placeholderOption = this.getPlaceholderOption();
                    this.opts.element.val(placeholderOption ? placeholderOption.val() : "");
                    this.selection.find(".select2-chosen").empty();
                    this.selection.removeData("select2-data");
                    this.setPlaceholder();
                    if (triggerChange !== false) {
                        this.opts.element.trigger({
                            type: "select2-removed",
                            val: this.id(data),
                            choice: data
                        });
                        this.triggerChange({
                            removed: data
                        });
                    }
                }
            },
            initSelection: function() {
                var selected;
                if (this.isPlaceholderOptionSelected()) {
                    this.updateSelection(null);
                    this.close();
                    this.setPlaceholder();
                } else {
                    var self = this;
                    this.opts.initSelection.call(null, this.opts.element, function(selected) {
                        if (selected !== undefined && selected !== null) {
                            self.updateSelection(selected);
                            self.close();
                            self.setPlaceholder();
                            self.nextSearchTerm = self.opts.nextSearchTerm(selected, self.search.val());
                        }
                    });
                }
            },
            isPlaceholderOptionSelected: function() {
                var placeholderOption;
                if (this.getPlaceholder() === undefined) return false;
                return ((placeholderOption = this.getPlaceholderOption()) !== undefined && placeholderOption.prop("selected")) ||
                    (this.opts.element.val() === "") ||
                    (this.opts.element.val() === undefined) ||
                    (this.opts.element.val() === null);
            },
            prepareOpts: function() {
                var opts = this.parent.prepareOpts.apply(this, arguments),
                    self = this;
                if (opts.element.get(0).tagName.toLowerCase() === "select") {
                    opts.initSelection = function(element, callback) {
                        var selected = element.find("option").filter(function() {
                            return this.selected && !this.disabled
                        });
                        callback(self.optionToData(selected));
                    };
                } else if ("data" in opts) {
                    opts.initSelection = opts.initSelection || function(element, callback) {
                        var id = element.val();
                        var match = null;
                        opts.query({
                            matcher: function(term, text, el) {
                                var is_match = equal(id, opts.id(el));
                                if (is_match) {
                                    match = el;
                                }
                                return is_match;
                            },
                            callback: !$.isFunction(callback) ? $.noop : function() {
                                callback(match);
                            }
                        });
                    };
                }
                return opts;
            },
            getPlaceholder: function() {
                if (this.select) {
                    if (this.getPlaceholderOption() === undefined) {
                        return undefined;
                    }
                }
                return this.parent.getPlaceholder.apply(this, arguments);
            },
            setPlaceholder: function() {
                var placeholder = this.getPlaceholder();
                if (this.isPlaceholderOptionSelected() && placeholder !== undefined) {
                    if (this.select && this.getPlaceholderOption() === undefined) return;
                    this.selection.find(".select2-chosen").html(this.opts.escapeMarkup(placeholder));
                    this.selection.addClass("select2-default");
                    this.container.removeClass("select2-allowclear");
                }
            },
            postprocessResults: function(data, initial, noHighlightUpdate) {
                var selected = 0,
                    self = this,
                    showSearchInput = true;
                this.findHighlightableChoices().each2(function(i, elm) {
                    if (equal(self.id(elm.data("select2-data")), self.opts.element.val())) {
                        selected = i;
                        return false;
                    }
                });
                if (noHighlightUpdate !== false) {
                    if (initial === true && selected >= 0) {
                        this.highlight(selected);
                    } else {
                        this.highlight(0);
                    }
                }
                if (initial === true) {
                    var min = this.opts.minimumResultsForSearch;
                    if (min >= 0) {
                        this.showSearch(countResults(data.results) >= min);
                    }
                }
            },
            showSearch: function(showSearchInput) {
                if (this.showSearchInput === showSearchInput) return;
                this.showSearchInput = showSearchInput;
                this.dropdown.find(".select2-search").toggleClass("select2-search-hidden", !showSearchInput);
                this.dropdown.find(".select2-search").toggleClass("select2-offscreen", !showSearchInput);
                $(this.dropdown, this.container).toggleClass("select2-with-searchbox", showSearchInput);
            },
            onSelect: function(data, options) {
                if (!this.triggerSelect(data)) {
                    return;
                }
                var old = this.opts.element.val(),
                    oldData = this.data();
                this.opts.element.val(this.id(data));
                this.updateSelection(data);
                this.opts.element.trigger({
                    type: "select2-selected",
                    val: this.id(data),
                    choice: data
                });
                this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val());
                this.close();
                if ((!options || !options.noFocus) && this.opts.shouldFocusInput(this)) {
                    this.focusser.focus();
                }
                if (!equal(old, this.id(data))) {
                    this.triggerChange({
                        added: data,
                        removed: oldData
                    });
                }
            },
            updateSelection: function(data) {
                var container = this.selection.find(".select2-chosen"),
                    formatted, cssClass;
                this.selection.data("select2-data", data);
                container.empty();
                if (data !== null) {
                    formatted = this.opts.formatSelection(data, container, this.opts.escapeMarkup);
                }
                if (formatted !== undefined) {
                    container.append(formatted);
                }
                cssClass = this.opts.formatSelectionCssClass(data, container);
                if (cssClass !== undefined) {
                    container.addClass(cssClass);
                }
                this.selection.removeClass("select2-default");
                if (this.opts.allowClear && this.getPlaceholder() !== undefined) {
                    this.container.addClass("select2-allowclear");
                }
            },
            val: function() {
                var val,
                    triggerChange = false,
                    data = null,
                    self = this,
                    oldData = this.data();
                if (arguments.length === 0) {
                    return this.opts.element.val();
                }
                val = arguments[0];
                if (arguments.length > 1) {
                    triggerChange = arguments[1];
                }
                if (this.select) {
                    this.select
                        .val(val)
                        .find("option").filter(function() {
                            return this.selected
                        }).each2(function(i, elm) {
                            data = self.optionToData(elm);
                            return false;
                        });
                    this.updateSelection(data);
                    this.setPlaceholder();
                    if (triggerChange) {
                        this.triggerChange({
                            added: data,
                            removed: oldData
                        });
                    }
                } else {
                    if (!val && val !== 0) {
                        this.clear(triggerChange);
                        return;
                    }
                    if (this.opts.initSelection === undefined) {
                        throw new Error("cannot call val() if initSelection() is not defined");
                    }
                    this.opts.element.val(val);
                    this.opts.initSelection(this.opts.element, function(data) {
                        self.opts.element.val(!data ? "" : self.id(data));
                        self.updateSelection(data);
                        self.setPlaceholder();
                        if (triggerChange) {
                            self.triggerChange({
                                added: data,
                                removed: oldData
                            });
                        }
                    });
                }
            },
            clearSearch: function() {
                this.search.val("");
                this.focusser.val("");
            },
            data: function(value) {
                var data,
                    triggerChange = false;
                if (arguments.length === 0) {
                    data = this.selection.data("select2-data");
                    if (data == undefined) data = null;
                    return data;
                } else {
                    if (arguments.length > 1) {
                        triggerChange = arguments[1];
                    }
                    if (!value) {
                        this.clear(triggerChange);
                    } else {
                        data = this.data();
                        this.opts.element.val(!value ? "" : this.id(value));
                        this.updateSelection(value);
                        if (triggerChange) {
                            this.triggerChange({
                                added: value,
                                removed: data
                            });
                        }
                    }
                }
            }
        });
        MultiSelect2 = clazz(AbstractSelect2, {
            createContainer: function() {
                var container = $(document.createElement("div")).attr({
                    "class": "select2-container select2-container-multi"
                }).html([
                    "<ul class='select2-choices'>",
                    "  <li class='select2-search-field'>",
                    "    <label for='' class='select2-offscreen'></label>",
                    "    <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input'>",
                    "  </li>",
                    "</ul>",
                    "<div class='select2-drop select2-drop-multi select2-display-none'>",
                    "   <ul class='select2-results'>",
                    "   </ul>",
                    "</div>"
                ].join(""));
                return container;
            },
            prepareOpts: function() {
                var opts = this.parent.prepareOpts.apply(this, arguments),
                    self = this;
                if (opts.element.get(0).tagName.toLowerCase() === "select") {
                    opts.initSelection = function(element, callback) {
                        var data = [];
                        element.find("option").filter(function() {
                            return this.selected && !this.disabled
                        }).each2(function(i, elm) {
                            data.push(self.optionToData(elm));
                        });
                        callback(data);
                    };
                } else if ("data" in opts) {
                    opts.initSelection = opts.initSelection || function(element, callback) {
                        var ids = splitVal(element.val(), opts.separator);
                        var matches = [];
                        opts.query({
                            matcher: function(term, text, el) {
                                var is_match = $.grep(ids, function(id) {
                                    return equal(id, opts.id(el));
                                }).length;
                                if (is_match) {
                                    matches.push(el);
                                }
                                return is_match;
                            },
                            callback: !$.isFunction(callback) ? $.noop : function() {
                                var ordered = [];
                                for (var i = 0; i < ids.length; i++) {
                                    var id = ids[i];
                                    for (var j = 0; j < matches.length; j++) {
                                        var match = matches[j];
                                        if (equal(id, opts.id(match))) {
                                            ordered.push(match);
                                            matches.splice(j, 1);
                                            break;
                                        }
                                    }
                                }
                                callback(ordered);
                            }
                        });
                    };
                }
                return opts;
            },
            selectChoice: function(choice) {
                var selected = this.container.find(".select2-search-choice-focus");
                if (selected.length && choice && choice[0] == selected[0]) {} else {
                    if (selected.length) {
                        this.opts.element.trigger("choice-deselected", selected);
                    }
                    selected.removeClass("select2-search-choice-focus");
                    if (choice && choice.length) {
                        this.close();
                        choice.addClass("select2-search-choice-focus");
                        this.opts.element.trigger("choice-selected", choice);
                    }
                }
            },
            destroy: function() {
                $("label[for='" + this.search.attr('id') + "']")
                    .attr('for', this.opts.element.attr("id"));
                this.parent.destroy.apply(this, arguments);
                cleanupJQueryElements.call(this,
                    "searchContainer",
                    "selection"
                );
            },
            initContainer: function() {
                var selector = ".select2-choices",
                    selection;
                this.searchContainer = this.container.find(".select2-search-field");
                this.selection = selection = this.container.find(selector);
                var _this = this;
                this.selection.on("click", ".select2-search-choice:not(.select2-locked)", function(e) {
                    _this.search[0].focus();
                    _this.selectChoice($(this));
                });
                this.search.attr("id", "s2id_autogen" + nextUid());
                this.search.prev()
                    .text($("label[for='" + this.opts.element.attr("id") + "']").text())
                    .attr('for', this.search.attr('id'));
                this.search.on("input paste", this.bind(function() {
                    if (this.search.attr('placeholder') && this.search.val().length == 0) return;
                    if (!this.isInterfaceEnabled()) return;
                    if (!this.opened()) {
                        this.open();
                    }
                }));
                this.search.attr("tabindex", this.elementTabIndex);
                this.keydowns = 0;
                this.search.on("keydown", this.bind(function(e) {
                    if (!this.isInterfaceEnabled()) return;
                    ++this.keydowns;
                    var selected = selection.find(".select2-search-choice-focus");
                    var prev = selected.prev(".select2-search-choice:not(.select2-locked)");
                    var next = selected.next(".select2-search-choice:not(.select2-locked)");
                    var pos = getCursorInfo(this.search);
                    if (selected.length &&
                        (e.which == KEY.LEFT || e.which == KEY.RIGHT || e.which == KEY.BACKSPACE || e.which == KEY.DELETE || e.which == KEY.ENTER)) {
                        var selectedChoice = selected;
                        if (e.which == KEY.LEFT && prev.length) {
                            selectedChoice = prev;
                        } else if (e.which == KEY.RIGHT) {
                            selectedChoice = next.length ? next : null;
                        } else if (e.which === KEY.BACKSPACE) {
                            if (this.unselect(selected.first())) {
                                this.search.width(10);
                                selectedChoice = prev.length ? prev : next;
                            }
                        } else if (e.which == KEY.DELETE) {
                            if (this.unselect(selected.first())) {
                                this.search.width(10);
                                selectedChoice = next.length ? next : null;
                            }
                        } else if (e.which == KEY.ENTER) {
                            selectedChoice = null;
                        }
                        this.selectChoice(selectedChoice);
                        killEvent(e);
                        if (!selectedChoice || !selectedChoice.length) {
                            this.open();
                        }
                        return;
                    } else if (((e.which === KEY.BACKSPACE && this.keydowns == 1) ||
                            e.which == KEY.LEFT) && (pos.offset == 0 && !pos.length)) {
                        this.selectChoice(selection.find(".select2-search-choice:not(.select2-locked)").last());
                        killEvent(e);
                        return;
                    } else {
                        this.selectChoice(null);
                    }
                    if (this.opened()) {
                        switch (e.which) {
                            case KEY.UP:
                            case KEY.DOWN:
                                this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
                                killEvent(e);
                                return;
                            case KEY.ENTER:
                                this.selectHighlighted();
                                killEvent(e);
                                return;
                            case KEY.TAB:
                                this.selectHighlighted({
                                    noFocus: true
                                });
                                this.close();
                                return;
                            case KEY.ESC:
                                this.cancel(e);
                                killEvent(e);
                                return;
                        }
                    }
                    if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) ||
                        e.which === KEY.BACKSPACE || e.which === KEY.ESC) {
                        return;
                    }
                    if (e.which === KEY.ENTER) {
                        if (this.opts.openOnEnter === false) {
                            return;
                        } else if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) {
                            return;
                        }
                    }
                    this.open();
                    if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {
                        killEvent(e);
                    }
                    if (e.which === KEY.ENTER) {
                        killEvent(e);
                    }
                }));
                this.search.on("keyup", this.bind(function(e) {
                    this.keydowns = 0;
                    this.resizeSearch();
                }));
                this.search.on("blur", this.bind(function(e) {
                    this.container.removeClass("select2-container-active");
                    this.search.removeClass("select2-focused");
                    this.selectChoice(null);
                    if (!this.opened()) this.clearSearch();
                    e.stopImmediatePropagation();
                    this.opts.element.trigger($.Event("select2-blur"));
                }));
                this.container.on("click", selector, this.bind(function(e) {
                    if (!this.isInterfaceEnabled()) return;
                    if ($(e.target).closest(".select2-search-choice").length > 0) {
                        return;
                    }
                    this.selectChoice(null);
                    this.clearPlaceholder();
                    if (!this.container.hasClass("select2-container-active")) {
                        this.opts.element.trigger($.Event("select2-focus"));
                    }
                    this.open();
                    this.focusSearch();
                    e.preventDefault();
                }));
                this.container.on("focus", selector, this.bind(function() {
                    if (!this.isInterfaceEnabled()) return;
                    if (!this.container.hasClass("select2-container-active")) {
                        this.opts.element.trigger($.Event("select2-focus"));
                    }
                    this.container.addClass("select2-container-active");
                    this.dropdown.addClass("select2-drop-active");
                    this.clearPlaceholder();
                }));
                this.initContainerWidth();
                this.opts.element.addClass("select2-offscreen");
                this.clearSearch();
            },
            enableInterface: function() {
                if (this.parent.enableInterface.apply(this, arguments)) {
                    this.search.prop("disabled", !this.isInterfaceEnabled());
                }
            },
            initSelection: function() {
                var data;
                if (this.opts.element.val() === "" && this.opts.element.text() === "") {
                    this.updateSelection([]);
                    this.close();
                    this.clearSearch();
                }
                if (this.select || this.opts.element.val() !== "") {
                    var self = this;
                    this.opts.initSelection.call(null, this.opts.element, function(data) {
                        if (data !== undefined && data !== null) {
                            self.updateSelection(data);
                            self.close();
                            self.clearSearch();
                        }
                    });
                }
            },
            clearSearch: function() {
                var placeholder = this.getPlaceholder(),
                    maxWidth = this.getMaxSearchWidth();
                if (placeholder !== undefined && this.getVal().length === 0 && this.search.hasClass("select2-focused") === false) {
                    this.search.val(placeholder).addClass("select2-default");
                    this.search.width(maxWidth > 0 ? maxWidth : this.container.css("width"));
                } else {
                    this.search.val("").width(10);
                }
            },
            clearPlaceholder: function() {
                if (this.search.hasClass("select2-default")) {
                    this.search.val("").removeClass("select2-default");
                }
            },
            opening: function() {
                this.clearPlaceholder();
                this.resizeSearch();
                this.parent.opening.apply(this, arguments);
                this.focusSearch();
                if (this.search.val() === "") {
                    if (this.nextSearchTerm != undefined) {
                        this.search.val(this.nextSearchTerm);
                        this.search.select();
                    }
                }
                this.updateResults(true);
                if (this.opts.shouldFocusInput(this)) {
                    this.search.focus();
                }
                this.opts.element.trigger($.Event("select2-open"));
            },
            close: function() {
                if (!this.opened()) return;
                this.parent.close.apply(this, arguments);
            },
            focus: function() {
                this.close();
                this.search.focus();
            },
            isFocused: function() {
                return this.search.hasClass("select2-focused");
            },
            updateSelection: function(data) {
                var ids = [],
                    filtered = [],
                    self = this;
                $(data).each(function() {
                    if (indexOf(self.id(this), ids) < 0) {
                        ids.push(self.id(this));
                        filtered.push(this);
                    }
                });
                data = filtered;
                this.selection.find(".select2-search-choice").remove();
                $(data).each(function() {
                    self.addSelectedChoice(this);
                });
                self.postprocessResults();
            },
            tokenize: function() {
                var input = this.search.val();
                input = this.opts.tokenizer.call(this, input, this.data(), this.bind(this.onSelect), this.opts);
                if (input != null && input != undefined) {
                    this.search.val(input);
                    if (input.length > 0) {
                        this.open();
                    }
                }
            },
            onSelect: function(data, options) {
                if (!this.triggerSelect(data) || data.text === "") {
                    return;
                }
                this.addSelectedChoice(data);
                this.opts.element.trigger({
                    type: "selected",
                    val: this.id(data),
                    choice: data
                });
                this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val());
                this.clearSearch();
                this.updateResults();
                if (this.select || !this.opts.closeOnSelect) this.postprocessResults(data, false, this.opts.closeOnSelect === true);
                if (this.opts.closeOnSelect) {
                    this.close();
                    this.search.width(10);
                } else {
                    if (this.countSelectableResults() > 0) {
                        this.search.width(10);
                        this.resizeSearch();
                        if (this.getMaximumSelectionSize() > 0 && this.val().length >= this.getMaximumSelectionSize()) {
                            this.updateResults(true);
                        } else {
                            if (this.nextSearchTerm != undefined) {
                                this.search.val(this.nextSearchTerm);
                                this.updateResults();
                                this.search.select();
                            }
                        }
                        this.positionDropdown();
                    } else {
                        this.close();
                        this.search.width(10);
                    }
                }
                this.triggerChange({
                    added: data
                });
                if (!options || !options.noFocus)
                    this.focusSearch();
            },
            cancel: function() {
                this.close();
                this.focusSearch();
            },
            addSelectedChoice: function(data) {
                var enableChoice = !data.locked,
                    enabledItem = $(
                        "<li class='select2-search-choice'>" +
                        "    <div></div>" +
                        "    <a href='#' class='select2-search-choice-close' tabindex='-1'></a>" +
                        "</li>"),
                    disabledItem = $(
                        "<li class='select2-search-choice select2-locked'>" +
                        "<div></div>" +
                        "</li>");
                var choice = enableChoice ? enabledItem : disabledItem,
                    id = this.id(data),
                    val = this.getVal(),
                    formatted,
                    cssClass;
                formatted = this.opts.formatSelection(data, choice.find("div"), this.opts.escapeMarkup);
                if (formatted != undefined) {
                    choice.find("div").replaceWith("<div>" + formatted + "</div>");
                }
                cssClass = this.opts.formatSelectionCssClass(data, choice.find("div"));
                if (cssClass != undefined) {
                    choice.addClass(cssClass);
                }
                if (enableChoice) {
                    choice.find(".select2-search-choice-close")
                        .on("mousedown", killEvent)
                        .on("click dblclick", this.bind(function(e) {
                            if (!this.isInterfaceEnabled()) return;
                            this.unselect($(e.target));
                            this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
                            killEvent(e);
                            this.close();
                            this.focusSearch();
                        })).on("focus", this.bind(function() {
                            if (!this.isInterfaceEnabled()) return;
                            this.container.addClass("select2-container-active");
                            this.dropdown.addClass("select2-drop-active");
                        }));
                }
                choice.data("select2-data", data);
                choice.insertBefore(this.searchContainer);
                val.push(id);
                this.setVal(val);
            },
            unselect: function(selected) {
                var val = this.getVal(),
                    data,
                    index;
                selected = selected.closest(".select2-search-choice");
                if (selected.length === 0) {
                    throw "Invalid argument: " + selected + ". Must be .select2-search-choice";
                }
                data = selected.data("select2-data");
                if (!data) {
                    return;
                }
                var evt = $.Event("select2-removing");
                evt.val = this.id(data);
                evt.choice = data;
                this.opts.element.trigger(evt);
                if (evt.isDefaultPrevented()) {
                    return false;
                }
                while ((index = indexOf(this.id(data), val)) >= 0) {
                    val.splice(index, 1);
                    this.setVal(val);
                    if (this.select) this.postprocessResults();
                }
                selected.remove();
                this.opts.element.trigger({
                    type: "select2-removed",
                    val: this.id(data),
                    choice: data
                });
                this.triggerChange({
                    removed: data
                });
                return true;
            },
            postprocessResults: function(data, initial, noHighlightUpdate) {
                var val = this.getVal(),
                    choices = this.results.find(".select2-result"),
                    compound = this.results.find(".select2-result-with-children"),
                    self = this;
                choices.each2(function(i, choice) {
                    var id = self.id(choice.data("select2-data"));
                    if (indexOf(id, val) >= 0) {
                        choice.addClass("select2-selected");
                        choice.find(".select2-result-selectable").addClass("select2-selected");
                    }
                });
                compound.each2(function(i, choice) {
                    if (!choice.is('.select2-result-selectable') &&
                        choice.find(".select2-result-selectable:not(.select2-selected)").length === 0) {
                        choice.addClass("select2-selected");
                    }
                });
                if (this.highlight() == -1 && noHighlightUpdate !== false) {
                    self.highlight(0);
                }
                if (!this.opts.createSearchChoice && !choices.filter('.select2-result:not(.select2-selected)').length > 0) {
                    if (!data || data && !data.more && this.results.find(".select2-no-results").length === 0) {
                        if (checkFormatter(self.opts.formatNoMatches, "formatNoMatches")) {
                            this.results.append("<li class='select2-no-results'>" + evaluate(self.opts.formatNoMatches, self.opts.element, self.search.val()) + "</li>");
                        }
                    }
                }
            },
            getMaxSearchWidth: function() {
                return this.selection.width() - getSideBorderPadding(this.search);
            },
            resizeSearch: function() {
                var minimumWidth, left, maxWidth, containerLeft, searchWidth,
                    sideBorderPadding = getSideBorderPadding(this.search);
                minimumWidth = measureTextWidth(this.search) + 10;
                left = this.search.offset().left;
                maxWidth = this.selection.width();
                containerLeft = this.selection.offset().left;
                searchWidth = maxWidth - (left - containerLeft) - sideBorderPadding;
                if (searchWidth < minimumWidth) {
                    searchWidth = maxWidth - sideBorderPadding;
                }
                if (searchWidth < 40) {
                    searchWidth = maxWidth - sideBorderPadding;
                }
                if (searchWidth <= 0) {
                    searchWidth = minimumWidth;
                }
                this.search.width(Math.floor(searchWidth));
            },
            getVal: function() {
                var val;
                if (this.select) {
                    val = this.select.val();
                    return val === null ? [] : val;
                } else {
                    val = this.opts.element.val();
                    return splitVal(val, this.opts.separator);
                }
            },
            setVal: function(val) {
                var unique;
                if (this.select) {
                    this.select.val(val);
                } else {
                    unique = [];
                    $(val).each(function() {
                        if (indexOf(this, unique) < 0) unique.push(this);
                    });
                    this.opts.element.val(unique.length === 0 ? "" : unique.join(this.opts.separator));
                }
            },
            buildChangeDetails: function(old, current) {
                var current = current.slice(0),
                    old = old.slice(0);
                for (var i = 0; i < current.length; i++) {
                    for (var j = 0; j < old.length; j++) {
                        if (equal(this.opts.id(current[i]), this.opts.id(old[j]))) {
                            current.splice(i, 1);
                            if (i > 0) {
                                i--;
                            }
                            old.splice(j, 1);
                            j--;
                        }
                    }
                }
                return {
                    added: current,
                    removed: old
                };
            },
            val: function(val, triggerChange) {
                var oldData, self = this;
                if (arguments.length === 0) {
                    return this.getVal();
                }
                oldData = this.data();
                if (!oldData.length) oldData = [];
                if (!val && val !== 0) {
                    this.opts.element.val("");
                    this.updateSelection([]);
                    this.clearSearch();
                    if (triggerChange) {
                        this.triggerChange({
                            added: this.data(),
                            removed: oldData
                        });
                    }
                    return;
                }
                this.setVal(val);
                if (this.select) {
                    this.opts.initSelection(this.select, this.bind(this.updateSelection));
                    if (triggerChange) {
                        this.triggerChange(this.buildChangeDetails(oldData, this.data()));
                    }
                } else {
                    if (this.opts.initSelection === undefined) {
                        throw new Error("val() cannot be called if initSelection() is not defined");
                    }
                    this.opts.initSelection(this.opts.element, function(data) {
                        var ids = $.map(data, self.id);
                        self.setVal(ids);
                        self.updateSelection(data);
                        self.clearSearch();
                        if (triggerChange) {
                            self.triggerChange(self.buildChangeDetails(oldData, self.data()));
                        }
                    });
                }
                this.clearSearch();
            },
            onSortStart: function() {
                if (this.select) {
                    throw new Error("Sorting of elements is not supported when attached to <select>. Attach to <input type='hidden'/> instead.");
                }
                this.search.width(0);
                this.searchContainer.hide();
            },
            onSortEnd: function() {
                var val = [],
                    self = this;
                this.searchContainer.show();
                this.searchContainer.appendTo(this.searchContainer.parent());
                this.resizeSearch();
                this.selection.find(".select2-search-choice").each(function() {
                    val.push(self.opts.id($(this).data("select2-data")));
                });
                this.setVal(val);
                this.triggerChange();
            },
            data: function(values, triggerChange) {
                var self = this,
                    ids, old;
                if (arguments.length === 0) {
                    return this.selection
                        .children(".select2-search-choice")
                        .map(function() {
                            return $(this).data("select2-data");
                        })
                        .get();
                } else {
                    old = this.data();
                    if (!values) {
                        values = [];
                    }
                    ids = $.map(values, function(e) {
                        return self.opts.id(e);
                    });
                    this.setVal(ids);
                    this.updateSelection(values);
                    this.clearSearch();
                    if (triggerChange) {
                        this.triggerChange(this.buildChangeDetails(old, this.data()));
                    }
                }
            }
        });
        $.fn.select2 = function() {
            var args = Array.prototype.slice.call(arguments, 0),
                opts,
                select2,
                method, value, multiple,
                allowedMethods = ["val", "destroy", "opened", "open", "close", "focus", "isFocused", "container", "dropdown", "onSortStart", "onSortEnd", "enable", "disable", "readonly", "positionDropdown", "data", "search"],
                valueMethods = ["opened", "isFocused", "container", "dropdown"],
                propertyMethods = ["val", "data"],
                methodsMap = {
                    search: "externalSearch"
                };
            this.each(function() {
                if (args.length === 0 || typeof(args[0]) === "object") {
                    opts = args.length === 0 ? {} : $.extend({}, args[0]);
                    opts.element = $(this);
                    if (opts.element.get(0).tagName.toLowerCase() === "select") {
                        multiple = opts.element.prop("multiple");
                    } else {
                        multiple = opts.multiple || false;
                        if ("tags" in opts) {
                            opts.multiple = multiple = true;
                        }
                    }
                    select2 = multiple ? new window.Select2["class"].multi() : new window.Select2["class"].single();
                    select2.init(opts);
                } else if (typeof(args[0]) === "string") {
                    if (indexOf(args[0], allowedMethods) < 0) {
                        throw "Unknown method: " + args[0];
                    }
                    value = undefined;
                    select2 = $(this).data("select2");
                    if (select2 === undefined) return;
                    method = args[0];
                    if (method === "container") {
                        value = select2.container;
                    } else if (method === "dropdown") {
                        value = select2.dropdown;
                    } else {
                        if (methodsMap[method]) method = methodsMap[method];
                        value = select2[method].apply(select2, args.slice(1));
                    }
                    if (indexOf(args[0], valueMethods) >= 0 ||
                        (indexOf(args[0], propertyMethods) >= 0 && args.length == 1)) {
                        return false;
                    }
                } else {
                    throw "Invalid arguments to select2 plugin: " + args;
                }
            });
            return (value === undefined) ? this : value;
        };
        $.fn.select2.defaults = {
            width: "copy",
            loadMorePadding: 0,
            closeOnSelect: true,
            openOnEnter: true,
            containerCss: {},
            dropdownCss: {},
            containerCssClass: "",
            dropdownCssClass: "",
            formatResult: function(result, container, query, escapeMarkup) {
                var markup = [];
                markMatch(result.text, query.term, markup, escapeMarkup);
                return markup.join("");
            },
            formatSelection: function(data, container, escapeMarkup) {
                return data ? escapeMarkup(data.text) : undefined;
            },
            sortResults: function(results, container, query) {
                return results;
            },
            formatResultCssClass: function(data) {
                return data.css;
            },
            formatSelectionCssClass: function(data, container) {
                return undefined;
            },
            minimumResultsForSearch: 0,
            minimumInputLength: 0,
            maximumInputLength: null,
            maximumSelectionSize: 0,
            id: function(e) {
                return e == undefined ? null : e.id;
            },
            matcher: function(term, text) {
                return stripDiacritics('' + text).toUpperCase().indexOf(stripDiacritics('' + term).toUpperCase()) >= 0;
            },
            separator: ",",
            tokenSeparators: [],
            tokenizer: defaultTokenizer,
            escapeMarkup: defaultEscapeMarkup,
            blurOnChange: false,
            selectOnBlur: false,
            adaptContainerCssClass: function(c) {
                return c;
            },
            adaptDropdownCssClass: function(c) {
                return null;
            },
            nextSearchTerm: function(selectedObject, currentSearchTerm) {
                return undefined;
            },
            searchInputPlaceholder: '',
            createSearchChoicePosition: 'top',
            shouldFocusInput: function(instance) {
                var supportsTouchEvents = (('ontouchstart' in window) ||
                    (navigator.msMaxTouchPoints > 0));
                if (!supportsTouchEvents) {
                    return true;
                }
                if (instance.opts.minimumResultsForSearch < 0) {
                    return false;
                }
                return true;
            }
        };
        $.fn.select2.locales = [];
        $.fn.select2.locales['en'] = {
            formatMatches: function(matches) {
                if (matches === 1) {
                    return "One result is available, press enter to select it.";
                }
                return matches + " results are available, use up and down arrow keys to navigate.";
            },
            formatNoMatches: function() {
                return "No matches found";
            },
            formatAjaxError: function(jqXHR, textStatus, errorThrown) {
                return "Loading failed";
            },
            formatInputTooShort: function(input, min) {
                var n = min - input.length;
                return "Please enter " + n + " or more character" + (n == 1 ? "" : "s");
            },
            formatInputTooLong: function(input, max) {
                var n = input.length - max;
                return "Please delete " + n + " character" + (n == 1 ? "" : "s");
            },
            formatSelectionTooBig: function(limit) {
                return "You can only select " + limit + " item" + (limit == 1 ? "" : "s");
            },
            formatLoadMore: function(pageNumber) {
                return "Loading more results…";
            },
            formatSearching: function() {
                return "Searching…";
            },
        };
        $.extend($.fn.select2.defaults, $.fn.select2.locales['en']);
        $.fn.select2.ajaxDefaults = {
            transport: $.ajax,
            params: {
                type: "GET",
                cache: false,
                dataType: "json"
            }
        };
        window.Select2 = {
            query: {
                ajax: ajax,
                local: local,
                tags: tags
            },
            util: {
                debounce: debounce,
                markMatch: markMatch,
                escapeMarkup: defaultEscapeMarkup,
                stripDiacritics: stripDiacritics
            },
            "class": {
                "abstract": AbstractSelect2,
                "single": SingleSelect2,
                "multi": MultiSelect2
            }
        };
    }(jQuery));;
    /*! RESOURCE: /scripts/sp.geo.js */
    function spLoadMaps() {
        if (typeof g_google_maps_api_loaded == "undefined") {
            spLoadScript('https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true&callback=initMap');
            g_google_maps_api_loaded = true;
        } else
            CustomEvent.fireAll('map.initialized');
    }
    
    function spLoadScript(url) {
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = url;
        document.body.appendChild(script);
    }
    
    function initMap() {
        CustomEvent.fireAll('map.initialized');
    };
    /*! RESOURCE: /scripts/js_includes_ng_amb.js */
    /*! RESOURCE: /scripts/js_includes_amb.js */
    /*! RESOURCE: /scripts/thirdparty/cometd/jquery/jquery-1.11.0.min.js */
    /*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
    ! function(a, b) {
        "object" == typeof module && "object" == typeof module.exports ? module.exports = a.document ? b(a, !0) : function(a) {
            if (!a.document) throw new Error("jQuery requires a window with a document");
            return b(a)
        } : b(a)
    }("undefined" != typeof window ? window : this, function(a, b) {
        var c = [],
            d = c.slice,
            e = c.concat,
            f = c.push,
            g = c.indexOf,
            h = {},
            i = h.toString,
            j = h.hasOwnProperty,
            k = "".trim,
            l = {},
            m = "1.11.0",
            n = function(a, b) {
                return new n.fn.init(a, b)
            },
            o = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
            p = /^-ms-/,
            q = /-([\da-z])/gi,
            r = function(a, b) {
                return b.toUpperCase()
            };
        n.fn = n.prototype = {
            jquery: m,
            constructor: n,
            selector: "",
            length: 0,
            toArray: function() {
                return d.call(this)
            },
            get: function(a) {
                return null != a ? 0 > a ? this[a + this.length] : this[a] : d.call(this)
            },
            pushStack: function(a) {
                var b = n.merge(this.constructor(), a);
                return b.prevObject = this, b.context = this.context, b
            },
            each: function(a, b) {
                return n.each(this, a, b)
            },
            map: function(a) {
                return this.pushStack(n.map(this, function(b, c) {
                    return a.call(b, c, b)
                }))
            },
            slice: function() {
                return this.pushStack(d.apply(this, arguments))
            },
            first: function() {
                return this.eq(0)
            },
            last: function() {
                return this.eq(-1)
            },
            eq: function(a) {
                var b = this.length,
                    c = +a + (0 > a ? b : 0);
                return this.pushStack(c >= 0 && b > c ? [this[c]] : [])
            },
            end: function() {
                return this.prevObject || this.constructor(null)
            },
            push: f,
            sort: c.sort,
            splice: c.splice
        }, n.extend = n.fn.extend = function() {
            var a, b, c, d, e, f, g = arguments[0] || {},
                h = 1,
                i = arguments.length,
                j = !1;
            for ("boolean" == typeof g && (j = g, g = arguments[h] || {}, h++), "object" == typeof g || n.isFunction(g) || (g = {}), h === i && (g = this, h--); i > h; h++)
                if (null != (e = arguments[h]))
                    for (d in e) a = g[d], c = e[d], g !== c && (j && c && (n.isPlainObject(c) || (b = n.isArray(c))) ? (b ? (b = !1, f = a && n.isArray(a) ? a : []) : f = a && n.isPlainObject(a) ? a : {}, g[d] = n.extend(j, f, c)) : void 0 !== c && (g[d] = c));
            return g
        }, n.extend({
            expando: "jQuery" + (m + Math.random()).replace(/\D/g, ""),
            isReady: !0,
            error: function(a) {
                throw new Error(a)
            },
            noop: function() {},
            isFunction: function(a) {
                return "function" === n.type(a)
            },
            isArray: Array.isArray || function(a) {
                return "array" === n.type(a)
            },
            isWindow: function(a) {
                return null != a && a == a.window
            },
            isNumeric: function(a) {
                return a - parseFloat(a) >= 0
            },
            isEmptyObject: function(a) {
                var b;
                for (b in a) return !1;
                return !0
            },
            isPlainObject: function(a) {
                var b;
                if (!a || "object" !== n.type(a) || a.nodeType || n.isWindow(a)) return !1;
                try {
                    if (a.constructor && !j.call(a, "constructor") && !j.call(a.constructor.prototype, "isPrototypeOf")) return !1
                } catch (c) {
                    return !1
                }
                if (l.ownLast)
                    for (b in a) return j.call(a, b);
                for (b in a);
                return void 0 === b || j.call(a, b)
            },
            type: function(a) {
                return null == a ? a + "" : "object" == typeof a || "function" == typeof a ? h[i.call(a)] || "object" : typeof a
            },
            globalEval: function(b) {
                b && n.trim(b) && (a.execScript || function(b) {
                    a.eval.call(a, b)
                })(b)
            },
            camelCase: function(a) {
                return a.replace(p, "ms-").replace(q, r)
            },
            nodeName: function(a, b) {
                return a.nodeName && a.nodeName.toLowerCase() === b.toLowerCase()
            },
            each: function(a, b, c) {
                var d, e = 0,
                    f = a.length,
                    g = s(a);
                if (c) {
                    if (g) {
                        for (; f > e; e++)
                            if (d = b.apply(a[e], c), d === !1) break
                    } else
                        for (e in a)
                            if (d = b.apply(a[e], c), d === !1) break
                } else if (g) {
                    for (; f > e; e++)
                        if (d = b.call(a[e], e, a[e]), d === !1) break
                } else
                    for (e in a)
                        if (d = b.call(a[e], e, a[e]), d === !1) break;
                return a
            },
            trim: k && !k.call("\ufeff\xa0") ? function(a) {
                return null == a ? "" : k.call(a)
            } : function(a) {
                return null == a ? "" : (a + "").replace(o, "")
            },
            makeArray: function(a, b) {
                var c = b || [];
                return null != a && (s(Object(a)) ? n.merge(c, "string" == typeof a ? [a] : a) : f.call(c, a)), c
            },
            inArray: function(a, b, c) {
                var d;
                if (b) {
                    if (g) return g.call(b, a, c);
                    for (d = b.length, c = c ? 0 > c ? Math.max(0, d + c) : c : 0; d > c; c++)
                        if (c in b && b[c] === a) return c
                }
                return -1
            },
            merge: function(a, b) {
                var c = +b.length,
                    d = 0,
                    e = a.length;
                while (c > d) a[e++] = b[d++];
                if (c !== c)
                    while (void 0 !== b[d]) a[e++] = b[d++];
                return a.length = e, a
            },
            grep: function(a, b, c) {
                for (var d, e = [], f = 0, g = a.length, h = !c; g > f; f++) d = !b(a[f], f), d !== h && e.push(a[f]);
                return e
            },
            map: function(a, b, c) {
                var d, f = 0,
                    g = a.length,
                    h = s(a),
                    i = [];
                if (h)
                    for (; g > f; f++) d = b(a[f], f, c), null != d && i.push(d);
                else
                    for (f in a) d = b(a[f], f, c), null != d && i.push(d);
                return e.apply([], i)
            },
            guid: 1,
            proxy: function(a, b) {
                var c, e, f;
                return "string" == typeof b && (f = a[b], b = a, a = f), n.isFunction(a) ? (c = d.call(arguments, 2), e = function() {
                    return a.apply(b || this, c.concat(d.call(arguments)))
                }, e.guid = a.guid = a.guid || n.guid++, e) : void 0
            },
            now: function() {
                return +new Date
            },
            support: l
        }), n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(a, b) {
            h["[object " + b + "]"] = b.toLowerCase()
        });
    
        function s(a) {
            var b = a.length,
                c = n.type(a);
            return "function" === c || n.isWindow(a) ? !1 : 1 === a.nodeType && b ? !0 : "array" === c || 0 === b || "number" == typeof b && b > 0 && b - 1 in a
        }
        var t = function(a) {
            var b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s = "sizzle" + -new Date,
                t = a.document,
                u = 0,
                v = 0,
                w = eb(),
                x = eb(),
                y = eb(),
                z = function(a, b) {
                    return a === b && (j = !0), 0
                },
                A = "undefined",
                B = 1 << 31,
                C = {}.hasOwnProperty,
                D = [],
                E = D.pop,
                F = D.push,
                G = D.push,
                H = D.slice,
                I = D.indexOf || function(a) {
                    for (var b = 0, c = this.length; c > b; b++)
                        if (this[b] === a) return b;
                    return -1
                },
                J = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
                K = "[\\x20\\t\\r\\n\\f]",
                L = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
                M = L.replace("w", "w#"),
                N = "\\[" + K + "*(" + L + ")" + K + "*(?:([*^$|!~]?=)" + K + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + M + ")|)|)" + K + "*\\]",
                O = ":(" + L + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + N.replace(3, 8) + ")*)|.*)\\)|)",
                P = new RegExp("^" + K + "+|((?:^|[^\\\\])(?:\\\\.)*)" + K + "+$", "g"),
                Q = new RegExp("^" + K + "*," + K + "*"),
                R = new RegExp("^" + K + "*([>+~]|" + K + ")" + K + "*"),
                S = new RegExp("=" + K + "*([^\\]'\"]*?)" + K + "*\\]", "g"),
                T = new RegExp(O),
                U = new RegExp("^" + M + "$"),
                V = {
                    ID: new RegExp("^#(" + L + ")"),
                    CLASS: new RegExp("^\\.(" + L + ")"),
                    TAG: new RegExp("^(" + L.replace("w", "w*") + ")"),
                    ATTR: new RegExp("^" + N),
                    PSEUDO: new RegExp("^" + O),
                    CHILD: new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + K + "*(even|odd|(([+-]|)(\\d*)n|)" + K + "*(?:([+-]|)" + K + "*(\\d+)|))" + K + "*\\)|)", "i"),
                    bool: new RegExp("^(?:" + J + ")$", "i"),
                    needsContext: new RegExp("^" + K + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + K + "*((?:-\\d)?\\d*)" + K + "*\\)|)(?=[^-]|$)", "i")
                },
                W = /^(?:input|select|textarea|button)$/i,
                X = /^h\d$/i,
                Y = /^[^{]+\{\s*\[native \w/,
                Z = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
                $ = /[+~]/,
                _ = /'|\\/g,
                ab = new RegExp("\\\\([\\da-f]{1,6}" + K + "?|(" + K + ")|.)", "ig"),
                bb = function(a, b, c) {
                    var d = "0x" + b - 65536;
                    return d !== d || c ? b : 0 > d ? String.fromCharCode(d + 65536) : String.fromCharCode(d >> 10 | 55296, 1023 & d | 56320)
                };
            try {
                G.apply(D = H.call(t.childNodes), t.childNodes), D[t.childNodes.length].nodeType
            } catch (cb) {
                G = {
                    apply: D.length ? function(a, b) {
                        F.apply(a, H.call(b))
                    } : function(a, b) {
                        var c = a.length,
                            d = 0;
                        while (a[c++] = b[d++]);
                        a.length = c - 1
                    }
                }
            }
    
            function db(a, b, d, e) {
                var f, g, h, i, j, m, p, q, u, v;
                if ((b ? b.ownerDocument || b : t) !== l && k(b), b = b || l, d = d || [], !a || "string" != typeof a) return d;
                if (1 !== (i = b.nodeType) && 9 !== i) return [];
                if (n && !e) {
                    if (f = Z.exec(a))
                        if (h = f[1]) {
                            if (9 === i) {
                                if (g = b.getElementById(h), !g || !g.parentNode) return d;
                                if (g.id === h) return d.push(g), d
                            } else if (b.ownerDocument && (g = b.ownerDocument.getElementById(h)) && r(b, g) && g.id === h) return d.push(g), d
                        } else {
                            if (f[2]) return G.apply(d, b.getElementsByTagName(a)), d;
                            if ((h = f[3]) && c.getElementsByClassName && b.getElementsByClassName) return G.apply(d, b.getElementsByClassName(h)), d
                        }
                    if (c.qsa && (!o || !o.test(a))) {
                        if (q = p = s, u = b, v = 9 === i && a, 1 === i && "object" !== b.nodeName.toLowerCase()) {
                            m = ob(a), (p = b.getAttribute("id")) ? q = p.replace(_, "\\$&") : b.setAttribute("id", q), q = "[id='" + q + "'] ", j = m.length;
                            while (j--) m[j] = q + pb(m[j]);
                            u = $.test(a) && mb(b.parentNode) || b, v = m.join(",")
                        }
                        if (v) try {
                            return G.apply(d, u.querySelectorAll(v)), d
                        } catch (w) {} finally {
                            p || b.removeAttribute("id")
                        }
                    }
                }
                return xb(a.replace(P, "$1"), b, d, e)
            }
    
            function eb() {
                var a = [];
    
                function b(c, e) {
                    return a.push(c + " ") > d.cacheLength && delete b[a.shift()], b[c + " "] = e
                }
                return b
            }
    
            function fb(a) {
                return a[s] = !0, a
            }
    
            function gb(a) {
                var b = l.createElement("div");
                try {
                    return !!a(b)
                } catch (c) {
                    return !1
                } finally {
                    b.parentNode && b.parentNode.removeChild(b), b = null
                }
            }
    
            function hb(a, b) {
                var c = a.split("|"),
                    e = a.length;
                while (e--) d.attrHandle[c[e]] = b
            }
    
            function ib(a, b) {
                var c = b && a,
                    d = c && 1 === a.nodeType && 1 === b.nodeType && (~b.sourceIndex || B) - (~a.sourceIndex || B);
                if (d) return d;
                if (c)
                    while (c = c.nextSibling)
                        if (c === b) return -1;
                return a ? 1 : -1
            }
    
            function jb(a) {
                return function(b) {
                    var c = b.nodeName.toLowerCase();
                    return "input" === c && b.type === a
                }
            }
    
            function kb(a) {
                return function(b) {
                    var c = b.nodeName.toLowerCase();
                    return ("input" === c || "button" === c) && b.type === a
                }
            }
    
            function lb(a) {
                return fb(function(b) {
                    return b = +b, fb(function(c, d) {
                        var e, f = a([], c.length, b),
                            g = f.length;
                        while (g--) c[e = f[g]] && (c[e] = !(d[e] = c[e]))
                    })
                })
            }
    
            function mb(a) {
                return a && typeof a.getElementsByTagName !== A && a
            }
            c = db.support = {}, f = db.isXML = function(a) {
                var b = a && (a.ownerDocument || a).documentElement;
                return b ? "HTML" !== b.nodeName : !1
            }, k = db.setDocument = function(a) {
                var b, e = a ? a.ownerDocument || a : t,
                    g = e.defaultView;
                return e !== l && 9 === e.nodeType && e.documentElement ? (l = e, m = e.documentElement, n = !f(e), g && g !== g.top && (g.addEventListener ? g.addEventListener("unload", function() {
                    k()
                }, !1) : g.attachEvent && g.attachEvent("onunload", function() {
                    k()
                })), c.attributes = gb(function(a) {
                    return a.className = "i", !a.getAttribute("className")
                }), c.getElementsByTagName = gb(function(a) {
                    return a.appendChild(e.createComment("")), !a.getElementsByTagName("*").length
                }), c.getElementsByClassName = Y.test(e.getElementsByClassName) && gb(function(a) {
                    return a.innerHTML = "<div class='a'></div><div class='a i'></div>", a.firstChild.className = "i", 2 === a.getElementsByClassName("i").length
                }), c.getById = gb(function(a) {
                    return m.appendChild(a).id = s, !e.getElementsByName || !e.getElementsByName(s).length
                }), c.getById ? (d.find.ID = function(a, b) {
                    if (typeof b.getElementById !== A && n) {
                        var c = b.getElementById(a);
                        return c && c.parentNode ? [c] : []
                    }
                }, d.filter.ID = function(a) {
                    var b = a.replace(ab, bb);
                    return function(a) {
                        return a.getAttribute("id") === b
                    }
                }) : (delete d.find.ID, d.filter.ID = function(a) {
                    var b = a.replace(ab, bb);
                    return function(a) {
                        var c = typeof a.getAttributeNode !== A && a.getAttributeNode("id");
                        return c && c.value === b
                    }
                }), d.find.TAG = c.getElementsByTagName ? function(a, b) {
                    return typeof b.getElementsByTagName !== A ? b.getElementsByTagName(a) : void 0
                } : function(a, b) {
                    var c, d = [],
                        e = 0,
                        f = b.getElementsByTagName(a);
                    if ("*" === a) {
                        while (c = f[e++]) 1 === c.nodeType && d.push(c);
                        return d
                    }
                    return f
                }, d.find.CLASS = c.getElementsByClassName && function(a, b) {
                    return typeof b.getElementsByClassName !== A && n ? b.getElementsByClassName(a) : void 0
                }, p = [], o = [], (c.qsa = Y.test(e.querySelectorAll)) && (gb(function(a) {
                    a.innerHTML = "<select t=''><option selected=''></option></select>", a.querySelectorAll("[t^='']").length && o.push("[*^$]=" + K + "*(?:''|\"\")"), a.querySelectorAll("[selected]").length || o.push("\\[" + K + "*(?:value|" + J + ")"), a.querySelectorAll(":checked").length || o.push(":checked")
                }), gb(function(a) {
                    var b = e.createElement("input");
                    b.setAttribute("type", "hidden"), a.appendChild(b).setAttribute("name", "D"), a.querySelectorAll("[name=d]").length && o.push("name" + K + "*[*^$|!~]?="), a.querySelectorAll(":enabled").length || o.push(":enabled", ":disabled"), a.querySelectorAll("*,:x"), o.push(",.*:")
                })), (c.matchesSelector = Y.test(q = m.webkitMatchesSelector || m.mozMatchesSelector || m.oMatchesSelector || m.msMatchesSelector)) && gb(function(a) {
                    c.disconnectedMatch = q.call(a, "div"), q.call(a, "[s!='']:x"), p.push("!=", O)
                }), o = o.length && new RegExp(o.join("|")), p = p.length && new RegExp(p.join("|")), b = Y.test(m.compareDocumentPosition), r = b || Y.test(m.contains) ? function(a, b) {
                    var c = 9 === a.nodeType ? a.documentElement : a,
                        d = b && b.parentNode;
                    return a === d || !(!d || 1 !== d.nodeType || !(c.contains ? c.contains(d) : a.compareDocumentPosition && 16 & a.compareDocumentPosition(d)))
                } : function(a, b) {
                    if (b)
                        while (b = b.parentNode)
                            if (b === a) return !0;
                    return !1
                }, z = b ? function(a, b) {
                    if (a === b) return j = !0, 0;
                    var d = !a.compareDocumentPosition - !b.compareDocumentPosition;
                    return d ? d : (d = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1, 1 & d || !c.sortDetached && b.compareDocumentPosition(a) === d ? a === e || a.ownerDocument === t && r(t, a) ? -1 : b === e || b.ownerDocument === t && r(t, b) ? 1 : i ? I.call(i, a) - I.call(i, b) : 0 : 4 & d ? -1 : 1)
                } : function(a, b) {
                    if (a === b) return j = !0, 0;
                    var c, d = 0,
                        f = a.parentNode,
                        g = b.parentNode,
                        h = [a],
                        k = [b];
                    if (!f || !g) return a === e ? -1 : b === e ? 1 : f ? -1 : g ? 1 : i ? I.call(i, a) - I.call(i, b) : 0;
                    if (f === g) return ib(a, b);
                    c = a;
                    while (c = c.parentNode) h.unshift(c);
                    c = b;
                    while (c = c.parentNode) k.unshift(c);
                    while (h[d] === k[d]) d++;
                    return d ? ib(h[d], k[d]) : h[d] === t ? -1 : k[d] === t ? 1 : 0
                }, e) : l
            }, db.matches = function(a, b) {
                return db(a, null, null, b)
            }, db.matchesSelector = function(a, b) {
                if ((a.ownerDocument || a) !== l && k(a), b = b.replace(S, "='$1']"), !(!c.matchesSelector || !n || p && p.test(b) || o && o.test(b))) try {
                    var d = q.call(a, b);
                    if (d || c.disconnectedMatch || a.document && 11 !== a.document.nodeType) return d
                } catch (e) {}
                return db(b, l, null, [a]).length > 0
            }, db.contains = function(a, b) {
                return (a.ownerDocument || a) !== l && k(a), r(a, b)
            }, db.attr = function(a, b) {
                (a.ownerDocument || a) !== l && k(a);
                var e = d.attrHandle[b.toLowerCase()],
                    f = e && C.call(d.attrHandle, b.toLowerCase()) ? e(a, b, !n) : void 0;
                return void 0 !== f ? f : c.attributes || !n ? a.getAttribute(b) : (f = a.getAttributeNode(b)) && f.specified ? f.value : null
            }, db.error = function(a) {
                throw new Error("Syntax error, unrecognized expression: " + a)
            }, db.uniqueSort = function(a) {
                var b, d = [],
                    e = 0,
                    f = 0;
                if (j = !c.detectDuplicates, i = !c.sortStable && a.slice(0), a.sort(z), j) {
                    while (b = a[f++]) b === a[f] && (e = d.push(f));
                    while (e--) a.splice(d[e], 1)
                }
                return i = null, a
            }, e = db.getText = function(a) {
                var b, c = "",
                    d = 0,
                    f = a.nodeType;
                if (f) {
                    if (1 === f || 9 === f || 11 === f) {
                        if ("string" == typeof a.textContent) return a.textContent;
                        for (a = a.firstChild; a; a = a.nextSibling) c += e(a)
                    } else if (3 === f || 4 === f) return a.nodeValue
                } else
                    while (b = a[d++]) c += e(b);
                return c
            }, d = db.selectors = {
                cacheLength: 50,
                createPseudo: fb,
                match: V,
                attrHandle: {},
                find: {},
                relative: {
                    ">": {
                        dir: "parentNode",
                        first: !0
                    },
                    " ": {
                        dir: "parentNode"
                    },
                    "+": {
                        dir: "previousSibling",
                        first: !0
                    },
                    "~": {
                        dir: "previousSibling"
                    }
                },
                preFilter: {
                    ATTR: function(a) {
                        return a[1] = a[1].replace(ab, bb), a[3] = (a[4] || a[5] || "").replace(ab, bb), "~=" === a[2] && (a[3] = " " + a[3] + " "), a.slice(0, 4)
                    },
                    CHILD: function(a) {
                        return a[1] = a[1].toLowerCase(), "nth" === a[1].slice(0, 3) ? (a[3] || db.error(a[0]), a[4] = +(a[4] ? a[5] + (a[6] || 1) : 2 * ("even" === a[3] || "odd" === a[3])), a[5] = +(a[7] + a[8] || "odd" === a[3])) : a[3] && db.error(a[0]), a
                    },
                    PSEUDO: function(a) {
                        var b, c = !a[5] && a[2];
                        return V.CHILD.test(a[0]) ? null : (a[3] && void 0 !== a[4] ? a[2] = a[4] : c && T.test(c) && (b = ob(c, !0)) && (b = c.indexOf(")", c.length - b) - c.length) && (a[0] = a[0].slice(0, b), a[2] = c.slice(0, b)), a.slice(0, 3))
                    }
                },
                filter: {
                    TAG: function(a) {
                        var b = a.replace(ab, bb).toLowerCase();
                        return "*" === a ? function() {
                            return !0
                        } : function(a) {
                            return a.nodeName && a.nodeName.toLowerCase() === b
                        }
                    },
                    CLASS: function(a) {
                        var b = w[a + " "];
                        return b || (b = new RegExp("(^|" + K + ")" + a + "(" + K + "|$)")) && w(a, function(a) {
                            return b.test("string" == typeof a.className && a.className || typeof a.getAttribute !== A && a.getAttribute("class") || "")
                        })
                    },
                    ATTR: function(a, b, c) {
                        return function(d) {
                            var e = db.attr(d, a);
                            return null == e ? "!=" === b : b ? (e += "", "=" === b ? e === c : "!=" === b ? e !== c : "^=" === b ? c && 0 === e.indexOf(c) : "*=" === b ? c && e.indexOf(c) > -1 : "$=" === b ? c && e.slice(-c.length) === c : "~=" === b ? (" " + e + " ").indexOf(c) > -1 : "|=" === b ? e === c || e.slice(0, c.length + 1) === c + "-" : !1) : !0
                        }
                    },
                    CHILD: function(a, b, c, d, e) {
                        var f = "nth" !== a.slice(0, 3),
                            g = "last" !== a.slice(-4),
                            h = "of-type" === b;
                        return 1 === d && 0 === e ? function(a) {
                            return !!a.parentNode
                        } : function(b, c, i) {
                            var j, k, l, m, n, o, p = f !== g ? "nextSibling" : "previousSibling",
                                q = b.parentNode,
                                r = h && b.nodeName.toLowerCase(),
                                t = !i && !h;
                            if (q) {
                                if (f) {
                                    while (p) {
                                        l = b;
                                        while (l = l[p])
                                            if (h ? l.nodeName.toLowerCase() === r : 1 === l.nodeType) return !1;
                                        o = p = "only" === a && !o && "nextSibling"
                                    }
                                    return !0
                                }
                                if (o = [g ? q.firstChild : q.lastChild], g && t) {
                                    k = q[s] || (q[s] = {}), j = k[a] || [], n = j[0] === u && j[1], m = j[0] === u && j[2], l = n && q.childNodes[n];
                                    while (l = ++n && l && l[p] || (m = n = 0) || o.pop())
                                        if (1 === l.nodeType && ++m && l === b) {
                                            k[a] = [u, n, m];
                                            break
                                        }
                                } else if (t && (j = (b[s] || (b[s] = {}))[a]) && j[0] === u) m = j[1];
                                else
                                    while (l = ++n && l && l[p] || (m = n = 0) || o.pop())
                                        if ((h ? l.nodeName.toLowerCase() === r : 1 === l.nodeType) && ++m && (t && ((l[s] || (l[s] = {}))[a] = [u, m]), l === b)) break;
                                return m -= e, m === d || m % d === 0 && m / d >= 0
                            }
                        }
                    },
                    PSEUDO: function(a, b) {
                        var c, e = d.pseudos[a] || d.setFilters[a.toLowerCase()] || db.error("unsupported pseudo: " + a);
                        return e[s] ? e(b) : e.length > 1 ? (c = [a, a, "", b], d.setFilters.hasOwnProperty(a.toLowerCase()) ? fb(function(a, c) {
                            var d, f = e(a, b),
                                g = f.length;
                            while (g--) d = I.call(a, f[g]), a[d] = !(c[d] = f[g])
                        }) : function(a) {
                            return e(a, 0, c)
                        }) : e
                    }
                },
                pseudos: {
                    not: fb(function(a) {
                        var b = [],
                            c = [],
                            d = g(a.replace(P, "$1"));
                        return d[s] ? fb(function(a, b, c, e) {
                            var f, g = d(a, null, e, []),
                                h = a.length;
                            while (h--)(f = g[h]) && (a[h] = !(b[h] = f))
                        }) : function(a, e, f) {
                            return b[0] = a, d(b, null, f, c), !c.pop()
                        }
                    }),
                    has: fb(function(a) {
                        return function(b) {
                            return db(a, b).length > 0
                        }
                    }),
                    contains: fb(function(a) {
                        return function(b) {
                            return (b.textContent || b.innerText || e(b)).indexOf(a) > -1
                        }
                    }),
                    lang: fb(function(a) {
                        return U.test(a || "") || db.error("unsupported lang: " + a), a = a.replace(ab, bb).toLowerCase(),
                            function(b) {
                                var c;
                                do
                                    if (c = n ? b.lang : b.getAttribute("xml:lang") || b.getAttribute("lang")) return c = c.toLowerCase(), c === a || 0 === c.indexOf(a + "-"); while ((b = b.parentNode) && 1 === b.nodeType);
                                return !1
                            }
                    }),
                    target: function(b) {
                        var c = a.location && a.location.hash;
                        return c && c.slice(1) === b.id
                    },
                    root: function(a) {
                        return a === m
                    },
                    focus: function(a) {
                        return a === l.activeElement && (!l.hasFocus || l.hasFocus()) && !!(a.type || a.href || ~a.tabIndex)
                    },
                    enabled: function(a) {
                        return a.disabled === !1
                    },
                    disabled: function(a) {
                        return a.disabled === !0
                    },
                    checked: function(a) {
                        var b = a.nodeName.toLowerCase();
                        return "input" === b && !!a.checked || "option" === b && !!a.selected
                    },
                    selected: function(a) {
                        return a.parentNode && a.parentNode.selectedIndex, a.selected === !0
                    },
                    empty: function(a) {
                        for (a = a.firstChild; a; a = a.nextSibling)
                            if (a.nodeType < 6) return !1;
                        return !0
                    },
                    parent: function(a) {
                        return !d.pseudos.empty(a)
                    },
                    header: function(a) {
                        return X.test(a.nodeName)
                    },
                    input: function(a) {
                        return W.test(a.nodeName)
                    },
                    button: function(a) {
                        var b = a.nodeName.toLowerCase();
                        return "input" === b && "button" === a.type || "button" === b
                    },
                    text: function(a) {
                        var b;
                        return "input" === a.nodeName.toLowerCase() && "text" === a.type && (null == (b = a.getAttribute("type")) || "text" === b.toLowerCase())
                    },
                    first: lb(function() {
                        return [0]
                    }),
                    last: lb(function(a, b) {
                        return [b - 1]
                    }),
                    eq: lb(function(a, b, c) {
                        return [0 > c ? c + b : c]
                    }),
                    even: lb(function(a, b) {
                        for (var c = 0; b > c; c += 2) a.push(c);
                        return a
                    }),
                    odd: lb(function(a, b) {
                        for (var c = 1; b > c; c += 2) a.push(c);
                        return a
                    }),
                    lt: lb(function(a, b, c) {
                        for (var d = 0 > c ? c + b : c; --d >= 0;) a.push(d);
                        return a
                    }),
                    gt: lb(function(a, b, c) {
                        for (var d = 0 > c ? c + b : c; ++d < b;) a.push(d);
                        return a
                    })
                }
            }, d.pseudos.nth = d.pseudos.eq;
            for (b in {
                    radio: !0,
                    checkbox: !0,
                    file: !0,
                    password: !0,
                    image: !0
                }) d.pseudos[b] = jb(b);
            for (b in {
                    submit: !0,
                    reset: !0
                }) d.pseudos[b] = kb(b);
    
            function nb() {}
            nb.prototype = d.filters = d.pseudos, d.setFilters = new nb;
    
            function ob(a, b) {
                var c, e, f, g, h, i, j, k = x[a + " "];
                if (k) return b ? 0 : k.slice(0);
                h = a, i = [], j = d.preFilter;
                while (h) {
                    (!c || (e = Q.exec(h))) && (e && (h = h.slice(e[0].length) || h), i.push(f = [])), c = !1, (e = R.exec(h)) && (c = e.shift(), f.push({
                        value: c,
                        type: e[0].replace(P, " ")
                    }), h = h.slice(c.length));
                    for (g in d.filter) !(e = V[g].exec(h)) || j[g] && !(e = j[g](e)) || (c = e.shift(), f.push({
                        value: c,
                        type: g,
                        matches: e
                    }), h = h.slice(c.length));
                    if (!c) break
                }
                return b ? h.length : h ? db.error(a) : x(a, i).slice(0)
            }
    
            function pb(a) {
                for (var b = 0, c = a.length, d = ""; c > b; b++) d += a[b].value;
                return d
            }
    
            function qb(a, b, c) {
                var d = b.dir,
                    e = c && "parentNode" === d,
                    f = v++;
                return b.first ? function(b, c, f) {
                    while (b = b[d])
                        if (1 === b.nodeType || e) return a(b, c, f)
                } : function(b, c, g) {
                    var h, i, j = [u, f];
                    if (g) {
                        while (b = b[d])
                            if ((1 === b.nodeType || e) && a(b, c, g)) return !0
                    } else
                        while (b = b[d])
                            if (1 === b.nodeType || e) {
                                if (i = b[s] || (b[s] = {}), (h = i[d]) && h[0] === u && h[1] === f) return j[2] = h[2];
                                if (i[d] = j, j[2] = a(b, c, g)) return !0
                            }
                }
            }
    
            function rb(a) {
                return a.length > 1 ? function(b, c, d) {
                    var e = a.length;
                    while (e--)
                        if (!a[e](b, c, d)) return !1;
                    return !0
                } : a[0]
            }
    
            function sb(a, b, c, d, e) {
                for (var f, g = [], h = 0, i = a.length, j = null != b; i > h; h++)(f = a[h]) && (!c || c(f, d, e)) && (g.push(f), j && b.push(h));
                return g
            }
    
            function tb(a, b, c, d, e, f) {
                return d && !d[s] && (d = tb(d)), e && !e[s] && (e = tb(e, f)), fb(function(f, g, h, i) {
                    var j, k, l, m = [],
                        n = [],
                        o = g.length,
                        p = f || wb(b || "*", h.nodeType ? [h] : h, []),
                        q = !a || !f && b ? p : sb(p, m, a, h, i),
                        r = c ? e || (f ? a : o || d) ? [] : g : q;
                    if (c && c(q, r, h, i), d) {
                        j = sb(r, n), d(j, [], h, i), k = j.length;
                        while (k--)(l = j[k]) && (r[n[k]] = !(q[n[k]] = l))
                    }
                    if (f) {
                        if (e || a) {
                            if (e) {
                                j = [], k = r.length;
                                while (k--)(l = r[k]) && j.push(q[k] = l);
                                e(null, r = [], j, i)
                            }
                            k = r.length;
                            while (k--)(l = r[k]) && (j = e ? I.call(f, l) : m[k]) > -1 && (f[j] = !(g[j] = l))
                        }
                    } else r = sb(r === g ? r.splice(o, r.length) : r), e ? e(null, g, r, i) : G.apply(g, r)
                })
            }
    
            function ub(a) {
                for (var b, c, e, f = a.length, g = d.relative[a[0].type], i = g || d.relative[" "], j = g ? 1 : 0, k = qb(function(a) {
                        return a === b
                    }, i, !0), l = qb(function(a) {
                        return I.call(b, a) > -1
                    }, i, !0), m = [function(a, c, d) {
                        return !g && (d || c !== h) || ((b = c).nodeType ? k(a, c, d) : l(a, c, d))
                    }]; f > j; j++)
                    if (c = d.relative[a[j].type]) m = [qb(rb(m), c)];
                    else {
                        if (c = d.filter[a[j].type].apply(null, a[j].matches), c[s]) {
                            for (e = ++j; f > e; e++)
                                if (d.relative[a[e].type]) break;
                            return tb(j > 1 && rb(m), j > 1 && pb(a.slice(0, j - 1).concat({
                                value: " " === a[j - 2].type ? "*" : ""
                            })).replace(P, "$1"), c, e > j && ub(a.slice(j, e)), f > e && ub(a = a.slice(e)), f > e && pb(a))
                        }
                        m.push(c)
                    }
                return rb(m)
            }
    
            function vb(a, b) {
                var c = b.length > 0,
                    e = a.length > 0,
                    f = function(f, g, i, j, k) {
                        var m, n, o, p = 0,
                            q = "0",
                            r = f && [],
                            s = [],
                            t = h,
                            v = f || e && d.find.TAG("*", k),
                            w = u += null == t ? 1 : Math.random() || .1,
                            x = v.length;
                        for (k && (h = g !== l && g); q !== x && null != (m = v[q]); q++) {
                            if (e && m) {
                                n = 0;
                                while (o = a[n++])
                                    if (o(m, g, i)) {
                                        j.push(m);
                                        break
                                    }
                                k && (u = w)
                            }
                            c && ((m = !o && m) && p--, f && r.push(m))
                        }
                        if (p += q, c && q !== p) {
                            n = 0;
                            while (o = b[n++]) o(r, s, g, i);
                            if (f) {
                                if (p > 0)
                                    while (q--) r[q] || s[q] || (s[q] = E.call(j));
                                s = sb(s)
                            }
                            G.apply(j, s), k && !f && s.length > 0 && p + b.length > 1 && db.uniqueSort(j)
                        }
                        return k && (u = w, h = t), r
                    };
                return c ? fb(f) : f
            }
            g = db.compile = function(a, b) {
                var c, d = [],
                    e = [],
                    f = y[a + " "];
                if (!f) {
                    b || (b = ob(a)), c = b.length;
                    while (c--) f = ub(b[c]), f[s] ? d.push(f) : e.push(f);
                    f = y(a, vb(e, d))
                }
                return f
            };
    
            function wb(a, b, c) {
                for (var d = 0, e = b.length; e > d; d++) db(a, b[d], c);
                return c
            }
    
            function xb(a, b, e, f) {
                var h, i, j, k, l, m = ob(a);
                if (!f && 1 === m.length) {
                    if (i = m[0] = m[0].slice(0), i.length > 2 && "ID" === (j = i[0]).type && c.getById && 9 === b.nodeType && n && d.relative[i[1].type]) {
                        if (b = (d.find.ID(j.matches[0].replace(ab, bb), b) || [])[0], !b) return e;
                        a = a.slice(i.shift().value.length)
                    }
                    h = V.needsContext.test(a) ? 0 : i.length;
                    while (h--) {
                        if (j = i[h], d.relative[k = j.type]) break;
                        if ((l = d.find[k]) && (f = l(j.matches[0].replace(ab, bb), $.test(i[0].type) && mb(b.parentNode) || b))) {
                            if (i.splice(h, 1), a = f.length && pb(i), !a) return G.apply(e, f), e;
                            break
                        }
                    }
                }
                return g(a, m)(f, b, !n, e, $.test(a) && mb(b.parentNode) || b), e
            }
            return c.sortStable = s.split("").sort(z).join("") === s, c.detectDuplicates = !!j, k(), c.sortDetached = gb(function(a) {
                return 1 & a.compareDocumentPosition(l.createElement("div"))
            }), gb(function(a) {
                return a.innerHTML = "<a href='#'></a>", "#" === a.firstChild.getAttribute("href")
            }) || hb("type|href|height|width", function(a, b, c) {
                return c ? void 0 : a.getAttribute(b, "type" === b.toLowerCase() ? 1 : 2)
            }), c.attributes && gb(function(a) {
                return a.innerHTML = "<input/>", a.firstChild.setAttribute("value", ""), "" === a.firstChild.getAttribute("value")
            }) || hb("value", function(a, b, c) {
                return c || "input" !== a.nodeName.toLowerCase() ? void 0 : a.defaultValue
            }), gb(function(a) {
                return null == a.getAttribute("disabled")
            }) || hb(J, function(a, b, c) {
                var d;
                return c ? void 0 : a[b] === !0 ? b.toLowerCase() : (d = a.getAttributeNode(b)) && d.specified ? d.value : null
            }), db
        }(a);
        n.find = t, n.expr = t.selectors, n.expr[":"] = n.expr.pseudos, n.unique = t.uniqueSort, n.text = t.getText, n.isXMLDoc = t.isXML, n.contains = t.contains;
        var u = n.expr.match.needsContext,
            v = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
            w = /^.[^:#\[\.,]*$/;
    
        function x(a, b, c) {
            if (n.isFunction(b)) return n.grep(a, function(a, d) {
                return !!b.call(a, d, a) !== c
            });
            if (b.nodeType) return n.grep(a, function(a) {
                return a === b !== c
            });
            if ("string" == typeof b) {
                if (w.test(b)) return n.filter(b, a, c);
                b = n.filter(b, a)
            }
            return n.grep(a, function(a) {
                return n.inArray(a, b) >= 0 !== c
            })
        }
        n.filter = function(a, b, c) {
            var d = b[0];
            return c && (a = ":not(" + a + ")"), 1 === b.length && 1 === d.nodeType ? n.find.matchesSelector(d, a) ? [d] : [] : n.find.matches(a, n.grep(b, function(a) {
                return 1 === a.nodeType
            }))
        }, n.fn.extend({
            find: function(a) {
                var b, c = [],
                    d = this,
                    e = d.length;
                if ("string" != typeof a) return this.pushStack(n(a).filter(function() {
                    for (b = 0; e > b; b++)
                        if (n.contains(d[b], this)) return !0
                }));
                for (b = 0; e > b; b++) n.find(a, d[b], c);
                return c = this.pushStack(e > 1 ? n.unique(c) : c), c.selector = this.selector ? this.selector + " " + a : a, c
            },
            filter: function(a) {
                return this.pushStack(x(this, a || [], !1))
            },
            not: function(a) {
                return this.pushStack(x(this, a || [], !0))
            },
            is: function(a) {
                return !!x(this, "string" == typeof a && u.test(a) ? n(a) : a || [], !1).length
            }
        });
        var y, z = a.document,
            A = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
            B = n.fn.init = function(a, b) {
                var c, d;
                if (!a) return this;
                if ("string" == typeof a) {
                    if (c = "<" === a.charAt(0) && ">" === a.charAt(a.length - 1) && a.length >= 3 ? [null, a, null] : A.exec(a), !c || !c[1] && b) return !b || b.jquery ? (b || y).find(a) : this.constructor(b).find(a);
                    if (c[1]) {
                        if (b = b instanceof n ? b[0] : b, n.merge(this, n.parseHTML(c[1], b && b.nodeType ? b.ownerDocument || b : z, !0)), v.test(c[1]) && n.isPlainObject(b))
                            for (c in b) n.isFunction(this[c]) ? this[c](b[c]) : this.attr(c, b[c]);
                        return this
                    }
                    if (d = z.getElementById(c[2]), d && d.parentNode) {
                        if (d.id !== c[2]) return y.find(a);
                        this.length = 1, this[0] = d
                    }
                    return this.context = z, this.selector = a, this
                }
                return a.nodeType ? (this.context = this[0] = a, this.length = 1, this) : n.isFunction(a) ? "undefined" != typeof y.ready ? y.ready(a) : a(n) : (void 0 !== a.selector && (this.selector = a.selector, this.context = a.context), n.makeArray(a, this))
            };
        B.prototype = n.fn, y = n(z);
        var C = /^(?:parents|prev(?:Until|All))/,
            D = {
                children: !0,
                contents: !0,
                next: !0,
                prev: !0
            };
        n.extend({
            dir: function(a, b, c) {
                var d = [],
                    e = a[b];
                while (e && 9 !== e.nodeType && (void 0 === c || 1 !== e.nodeType || !n(e).is(c))) 1 === e.nodeType && d.push(e), e = e[b];
                return d
            },
            sibling: function(a, b) {
                for (var c = []; a; a = a.nextSibling) 1 === a.nodeType && a !== b && c.push(a);
                return c
            }
        }), n.fn.extend({
            has: function(a) {
                var b, c = n(a, this),
                    d = c.length;
                return this.filter(function() {
                    for (b = 0; d > b; b++)
                        if (n.contains(this, c[b])) return !0
                })
            },
            closest: function(a, b) {
                for (var c, d = 0, e = this.length, f = [], g = u.test(a) || "string" != typeof a ? n(a, b || this.context) : 0; e > d; d++)
                    for (c = this[d]; c && c !== b; c = c.parentNode)
                        if (c.nodeType < 11 && (g ? g.index(c) > -1 : 1 === c.nodeType && n.find.matchesSelector(c, a))) {
                            f.push(c);
                            break
                        }
                return this.pushStack(f.length > 1 ? n.unique(f) : f)
            },
            index: function(a) {
                return a ? "string" == typeof a ? n.inArray(this[0], n(a)) : n.inArray(a.jquery ? a[0] : a, this) : this[0] && this[0].parentNode ? this.first().prevAll().length : -1
            },
            add: function(a, b) {
                return this.pushStack(n.unique(n.merge(this.get(), n(a, b))))
            },
            addBack: function(a) {
                return this.add(null == a ? this.prevObject : this.prevObject.filter(a))
            }
        });
    
        function E(a, b) {
            do a = a[b]; while (a && 1 !== a.nodeType);
            return a
        }
        n.each({
            parent: function(a) {
                var b = a.parentNode;
                return b && 11 !== b.nodeType ? b : null
            },
            parents: function(a) {
                return n.dir(a, "parentNode")
            },
            parentsUntil: function(a, b, c) {
                return n.dir(a, "parentNode", c)
            },
            next: function(a) {
                return E(a, "nextSibling")
            },
            prev: function(a) {
                return E(a, "previousSibling")
            },
            nextAll: function(a) {
                return n.dir(a, "nextSibling")
            },
            prevAll: function(a) {
                return n.dir(a, "previousSibling")
            },
            nextUntil: function(a, b, c) {
                return n.dir(a, "nextSibling", c)
            },
            prevUntil: function(a, b, c) {
                return n.dir(a, "previousSibling", c)
            },
            siblings: function(a) {
                return n.sibling((a.parentNode || {}).firstChild, a)
            },
            children: function(a) {
                return n.sibling(a.firstChild)
            },
            contents: function(a) {
                return n.nodeName(a, "iframe") ? a.contentDocument || a.contentWindow.document : n.merge([], a.childNodes)
            }
        }, function(a, b) {
            n.fn[a] = function(c, d) {
                var e = n.map(this, b, c);
                return "Until" !== a.slice(-5) && (d = c), d && "string" == typeof d && (e = n.filter(d, e)), this.length > 1 && (D[a] || (e = n.unique(e)), C.test(a) && (e = e.reverse())), this.pushStack(e)
            }
        });
        var F = /\S+/g,
            G = {};
    
        function H(a) {
            var b = G[a] = {};
            return n.each(a.match(F) || [], function(a, c) {
                b[c] = !0
            }), b
        }
        n.Callbacks = function(a) {
            a = "string" == typeof a ? G[a] || H(a) : n.extend({}, a);
            var b, c, d, e, f, g, h = [],
                i = !a.once && [],
                j = function(l) {
                    for (c = a.memory && l, d = !0, f = g || 0, g = 0, e = h.length, b = !0; h && e > f; f++)
                        if (h[f].apply(l[0], l[1]) === !1 && a.stopOnFalse) {
                            c = !1;
                            break
                        }
                    b = !1, h && (i ? i.length && j(i.shift()) : c ? h = [] : k.disable())
                },
                k = {
                    add: function() {
                        if (h) {
                            var d = h.length;
                            ! function f(b) {
                                n.each(b, function(b, c) {
                                    var d = n.type(c);
                                    "function" === d ? a.unique && k.has(c) || h.push(c) : c && c.length && "string" !== d && f(c)
                                })
                            }(arguments), b ? e = h.length : c && (g = d, j(c))
                        }
                        return this
                    },
                    remove: function() {
                        return h && n.each(arguments, function(a, c) {
                            var d;
                            while ((d = n.inArray(c, h, d)) > -1) h.splice(d, 1), b && (e >= d && e--, f >= d && f--)
                        }), this
                    },
                    has: function(a) {
                        return a ? n.inArray(a, h) > -1 : !(!h || !h.length)
                    },
                    empty: function() {
                        return h = [], e = 0, this
                    },
                    disable: function() {
                        return h = i = c = void 0, this
                    },
                    disabled: function() {
                        return !h
                    },
                    lock: function() {
                        return i = void 0, c || k.disable(), this
                    },
                    locked: function() {
                        return !i
                    },
                    fireWith: function(a, c) {
                        return !h || d && !i || (c = c || [], c = [a, c.slice ? c.slice() : c], b ? i.push(c) : j(c)), this
                    },
                    fire: function() {
                        return k.fireWith(this, arguments), this
                    },
                    fired: function() {
                        return !!d
                    }
                };
            return k
        }, n.extend({
            Deferred: function(a) {
                var b = [
                        ["resolve", "done", n.Callbacks("once memory"), "resolved"],
                        ["reject", "fail", n.Callbacks("once memory"), "rejected"],
                        ["notify", "progress", n.Callbacks("memory")]
                    ],
                    c = "pending",
                    d = {
                        state: function() {
                            return c
                        },
                        always: function() {
                            return e.done(arguments).fail(arguments), this
                        },
                        then: function() {
                            var a = arguments;
                            return n.Deferred(function(c) {
                                n.each(b, function(b, f) {
                                    var g = n.isFunction(a[b]) && a[b];
                                    e[f[1]](function() {
                                        var a = g && g.apply(this, arguments);
                                        a && n.isFunction(a.promise) ? a.promise().done(c.resolve).fail(c.reject).progress(c.notify) : c[f[0] + "With"](this === d ? c.promise() : this, g ? [a] : arguments)
                                    })
                                }), a = null
                            }).promise()
                        },
                        promise: function(a) {
                            return null != a ? n.extend(a, d) : d
                        }
                    },
                    e = {};
                return d.pipe = d.then, n.each(b, function(a, f) {
                    var g = f[2],
                        h = f[3];
                    d[f[1]] = g.add, h && g.add(function() {
                        c = h
                    }, b[1 ^ a][2].disable, b[2][2].lock), e[f[0]] = function() {
                        return e[f[0] + "With"](this === e ? d : this, arguments), this
                    }, e[f[0] + "With"] = g.fireWith
                }), d.promise(e), a && a.call(e, e), e
            },
            when: function(a) {
                var b = 0,
                    c = d.call(arguments),
                    e = c.length,
                    f = 1 !== e || a && n.isFunction(a.promise) ? e : 0,
                    g = 1 === f ? a : n.Deferred(),
                    h = function(a, b, c) {
                        return function(e) {
                            b[a] = this, c[a] = arguments.length > 1 ? d.call(arguments) : e, c === i ? g.notifyWith(b, c) : --f || g.resolveWith(b, c)
                        }
                    },
                    i, j, k;
                if (e > 1)
                    for (i = new Array(e), j = new Array(e), k = new Array(e); e > b; b++) c[b] && n.isFunction(c[b].promise) ? c[b].promise().done(h(b, k, c)).fail(g.reject).progress(h(b, j, i)) : --f;
                return f || g.resolveWith(k, c), g.promise()
            }
        });
        var I;
        n.fn.ready = function(a) {
            return n.ready.promise().done(a), this
        }, n.extend({
            isReady: !1,
            readyWait: 1,
            holdReady: function(a) {
                a ? n.readyWait++ : n.ready(!0)
            },
            ready: function(a) {
                if (a === !0 ? !--n.readyWait : !n.isReady) {
                    if (!z.body) return setTimeout(n.ready);
                    n.isReady = !0, a !== !0 && --n.readyWait > 0 || (I.resolveWith(z, [n]), n.fn.trigger && n(z).trigger("ready").off("ready"))
                }
            }
        });
    
        function J() {
            z.addEventListener ? (z.removeEventListener("DOMContentLoaded", K, !1), a.removeEventListener("load", K, !1)) : (z.detachEvent("onreadystatechange", K), a.detachEvent("onload", K))
        }
    
        function K() {
            (z.addEventListener || "load" === event.type || "complete" === z.readyState) && (J(), n.ready())
        }
        n.ready.promise = function(b) {
            if (!I)
                if (I = n.Deferred(), "complete" === z.readyState) setTimeout(n.ready);
                else if (z.addEventListener) z.addEventListener("DOMContentLoaded", K, !1), a.addEventListener("load", K, !1);
            else {
                z.attachEvent("onreadystatechange", K), a.attachEvent("onload", K);
                var c = !1;
                try {
                    c = null == a.frameElement && z.documentElement
                } catch (d) {}
                c && c.doScroll && ! function e() {
                    if (!n.isReady) {
                        try {
                            c.doScroll("left")
                        } catch (a) {
                            return setTimeout(e, 50)
                        }
                        J(), n.ready()
                    }
                }()
            }
            return I.promise(b)
        };
        var L = "undefined",
            M;
        for (M in n(l)) break;
        l.ownLast = "0" !== M, l.inlineBlockNeedsLayout = !1, n(function() {
                var a, b, c = z.getElementsByTagName("body")[0];
                c && (a = z.createElement("div"), a.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px", b = z.createElement("div"), c.appendChild(a).appendChild(b), typeof b.style.zoom !== L && (b.style.cssText = "border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1", (l.inlineBlockNeedsLayout = 3 === b.offsetWidth) && (c.style.zoom = 1)), c.removeChild(a), a = b = null)
            }),
            function() {
                var a = z.createElement("div");
                if (null == l.deleteExpando) {
                    l.deleteExpando = !0;
                    try {
                        delete a.test
                    } catch (b) {
                        l.deleteExpando = !1
                    }
                }
                a = null
            }(), n.acceptData = function(a) {
                var b = n.noData[(a.nodeName + " ").toLowerCase()],
                    c = +a.nodeType || 1;
                return 1 !== c && 9 !== c ? !1 : !b || b !== !0 && a.getAttribute("classid") === b
            };
        var N = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
            O = /([A-Z])/g;
    
        function P(a, b, c) {
            if (void 0 === c && 1 === a.nodeType) {
                var d = "data-" + b.replace(O, "-$1").toLowerCase();
                if (c = a.getAttribute(d), "string" == typeof c) {
                    try {
                        c = "true" === c ? !0 : "false" === c ? !1 : "null" === c ? null : +c + "" === c ? +c : N.test(c) ? n.parseJSON(c) : c
                    } catch (e) {}
                    n.data(a, b, c)
                } else c = void 0
            }
            return c
        }
    
        function Q(a) {
            var b;
            for (b in a)
                if (("data" !== b || !n.isEmptyObject(a[b])) && "toJSON" !== b) return !1;
            return !0
        }
    
        function R(a, b, d, e) {
            if (n.acceptData(a)) {
                var f, g, h = n.expando,
                    i = a.nodeType,
                    j = i ? n.cache : a,
                    k = i ? a[h] : a[h] && h;
                if (k && j[k] && (e || j[k].data) || void 0 !== d || "string" != typeof b) return k || (k = i ? a[h] = c.pop() || n.guid++ : h), j[k] || (j[k] = i ? {} : {
                    toJSON: n.noop
                }), ("object" == typeof b || "function" == typeof b) && (e ? j[k] = n.extend(j[k], b) : j[k].data = n.extend(j[k].data, b)), g = j[k], e || (g.data || (g.data = {}), g = g.data), void 0 !== d && (g[n.camelCase(b)] = d), "string" == typeof b ? (f = g[b], null == f && (f = g[n.camelCase(b)])) : f = g, f
            }
        }
    
        function S(a, b, c) {
            if (n.acceptData(a)) {
                var d, e, f = a.nodeType,
                    g = f ? n.cache : a,
                    h = f ? a[n.expando] : n.expando;
                if (g[h]) {
                    if (b && (d = c ? g[h] : g[h].data)) {
                        n.isArray(b) ? b = b.concat(n.map(b, n.camelCase)) : b in d ? b = [b] : (b = n.camelCase(b), b = b in d ? [b] : b.split(" ")), e = b.length;
                        while (e--) delete d[b[e]];
                        if (c ? !Q(d) : !n.isEmptyObject(d)) return
                    }(c || (delete g[h].data, Q(g[h]))) && (f ? n.cleanData([a], !0) : l.deleteExpando || g != g.window ? delete g[h] : g[h] = null)
                }
            }
        }
        n.extend({
            cache: {},
            noData: {
                "applet ": !0,
                "embed ": !0,
                "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
            },
            hasData: function(a) {
                return a = a.nodeType ? n.cache[a[n.expando]] : a[n.expando], !!a && !Q(a)
            },
            data: function(a, b, c) {
                return R(a, b, c)
            },
            removeData: function(a, b) {
                return S(a, b)
            },
            _data: function(a, b, c) {
                return R(a, b, c, !0)
            },
            _removeData: function(a, b) {
                return S(a, b, !0)
            }
        }), n.fn.extend({
            data: function(a, b) {
                var c, d, e, f = this[0],
                    g = f && f.attributes;
                if (void 0 === a) {
                    if (this.length && (e = n.data(f), 1 === f.nodeType && !n._data(f, "parsedAttrs"))) {
                        c = g.length;
                        while (c--) d = g[c].name, 0 === d.indexOf("data-") && (d = n.camelCase(d.slice(5)), P(f, d, e[d]));
                        n._data(f, "parsedAttrs", !0)
                    }
                    return e
                }
                return "object" == typeof a ? this.each(function() {
                    n.data(this, a)
                }) : arguments.length > 1 ? this.each(function() {
                    n.data(this, a, b)
                }) : f ? P(f, a, n.data(f, a)) : void 0
            },
            removeData: function(a) {
                return this.each(function() {
                    n.removeData(this, a)
                })
            }
        }), n.extend({
            queue: function(a, b, c) {
                var d;
                return a ? (b = (b || "fx") + "queue", d = n._data(a, b), c && (!d || n.isArray(c) ? d = n._data(a, b, n.makeArray(c)) : d.push(c)), d || []) : void 0
            },
            dequeue: function(a, b) {
                b = b || "fx";
                var c = n.queue(a, b),
                    d = c.length,
                    e = c.shift(),
                    f = n._queueHooks(a, b),
                    g = function() {
                        n.dequeue(a, b)
                    };
                "inprogress" === e && (e = c.shift(), d--), e && ("fx" === b && c.unshift("inprogress"), delete f.stop, e.call(a, g, f)), !d && f && f.empty.fire()
            },
            _queueHooks: function(a, b) {
                var c = b + "queueHooks";
                return n._data(a, c) || n._data(a, c, {
                    empty: n.Callbacks("once memory").add(function() {
                        n._removeData(a, b + "queue"), n._removeData(a, c)
                    })
                })
            }
        }), n.fn.extend({
            queue: function(a, b) {
                var c = 2;
                return "string" != typeof a && (b = a, a = "fx", c--), arguments.length < c ? n.queue(this[0], a) : void 0 === b ? this : this.each(function() {
                    var c = n.queue(this, a, b);
                    n._queueHooks(this, a), "fx" === a && "inprogress" !== c[0] && n.dequeue(this, a)
                })
            },
            dequeue: function(a) {
                return this.each(function() {
                    n.dequeue(this, a)
                })
            },
            clearQueue: function(a) {
                return this.queue(a || "fx", [])
            },
            promise: function(a, b) {
                var c, d = 1,
                    e = n.Deferred(),
                    f = this,
                    g = this.length,
                    h = function() {
                        --d || e.resolveWith(f, [f])
                    };
                "string" != typeof a && (b = a, a = void 0), a = a || "fx";
                while (g--) c = n._data(f[g], a + "queueHooks"), c && c.empty && (d++, c.empty.add(h));
                return h(), e.promise(b)
            }
        });
        var T = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
            U = ["Top", "Right", "Bottom", "Left"],
            V = function(a, b) {
                return a = b || a, "none" === n.css(a, "display") || !n.contains(a.ownerDocument, a)
            },
            W = n.access = function(a, b, c, d, e, f, g) {
                var h = 0,
                    i = a.length,
                    j = null == c;
                if ("object" === n.type(c)) {
                    e = !0;
                    for (h in c) n.access(a, b, h, c[h], !0, f, g)
                } else if (void 0 !== d && (e = !0, n.isFunction(d) || (g = !0), j && (g ? (b.call(a, d), b = null) : (j = b, b = function(a, b, c) {
                        return j.call(n(a), c)
                    })), b))
                    for (; i > h; h++) b(a[h], c, g ? d : d.call(a[h], h, b(a[h], c)));
                return e ? a : j ? b.call(a) : i ? b(a[0], c) : f
            },
            X = /^(?:checkbox|radio)$/i;
        ! function() {
            var a = z.createDocumentFragment(),
                b = z.createElement("div"),
                c = z.createElement("input");
            if (b.setAttribute("className", "t"), b.innerHTML = "  <link/><table></table><a href='/a'>a</a>", l.leadingWhitespace = 3 === b.firstChild.nodeType, l.tbody = !b.getElementsByTagName("tbody").length, l.htmlSerialize = !!b.getElementsByTagName("link").length, l.html5Clone = "<:nav></:nav>" !== z.createElement("nav").cloneNode(!0).outerHTML, c.type = "checkbox", c.checked = !0, a.appendChild(c), l.appendChecked = c.checked, b.innerHTML = "<textarea>x</textarea>", l.noCloneChecked = !!b.cloneNode(!0).lastChild.defaultValue, a.appendChild(b), b.innerHTML = "<input type='radio' checked='checked' name='t'/>", l.checkClone = b.cloneNode(!0).cloneNode(!0).lastChild.checked, l.noCloneEvent = !0, b.attachEvent && (b.attachEvent("onclick", function() {
                    l.noCloneEvent = !1
                }), b.cloneNode(!0).click()), null == l.deleteExpando) {
                l.deleteExpando = !0;
                try {
                    delete b.test
                } catch (d) {
                    l.deleteExpando = !1
                }
            }
            a = b = c = null
        }(),
        function() {
            var b, c, d = z.createElement("div");
            for (b in {
                    submit: !0,
                    change: !0,
                    focusin: !0
                }) c = "on" + b, (l[b + "Bubbles"] = c in a) || (d.setAttribute(c, "t"), l[b + "Bubbles"] = d.attributes[c].expando === !1);
            d = null
        }();
        var Y = /^(?:input|select|textarea)$/i,
            Z = /^key/,
            $ = /^(?:mouse|contextmenu)|click/,
            _ = /^(?:focusinfocus|focusoutblur)$/,
            ab = /^([^.]*)(?:\.(.+)|)$/;
    
        function bb() {
            return !0
        }
    
        function cb() {
            return !1
        }
    
        function db() {
            try {
                return z.activeElement
            } catch (a) {}
        }
        n.event = {
            global: {},
            add: function(a, b, c, d, e) {
                var f, g, h, i, j, k, l, m, o, p, q, r = n._data(a);
                if (r) {
                    c.handler && (i = c, c = i.handler, e = i.selector), c.guid || (c.guid = n.guid++), (g = r.events) || (g = r.events = {}), (k = r.handle) || (k = r.handle = function(a) {
                        return typeof n === L || a && n.event.triggered === a.type ? void 0 : n.event.dispatch.apply(k.elem, arguments)
                    }, k.elem = a), b = (b || "").match(F) || [""], h = b.length;
                    while (h--) f = ab.exec(b[h]) || [], o = q = f[1], p = (f[2] || "").split(".").sort(), o && (j = n.event.special[o] || {}, o = (e ? j.delegateType : j.bindType) || o, j = n.event.special[o] || {}, l = n.extend({
                        type: o,
                        origType: q,
                        data: d,
                        handler: c,
                        guid: c.guid,
                        selector: e,
                        needsContext: e && n.expr.match.needsContext.test(e),
                        namespace: p.join(".")
                    }, i), (m = g[o]) || (m = g[o] = [], m.delegateCount = 0, j.setup && j.setup.call(a, d, p, k) !== !1 || (a.addEventListener ? a.addEventListener(o, k, !1) : a.attachEvent && a.attachEvent("on" + o, k))), j.add && (j.add.call(a, l), l.handler.guid || (l.handler.guid = c.guid)), e ? m.splice(m.delegateCount++, 0, l) : m.push(l), n.event.global[o] = !0);
                    a = null
                }
            },
            remove: function(a, b, c, d, e) {
                var f, g, h, i, j, k, l, m, o, p, q, r = n.hasData(a) && n._data(a);
                if (r && (k = r.events)) {
                    b = (b || "").match(F) || [""], j = b.length;
                    while (j--)
                        if (h = ab.exec(b[j]) || [], o = q = h[1], p = (h[2] || "").split(".").sort(), o) {
                            l = n.event.special[o] || {}, o = (d ? l.delegateType : l.bindType) || o, m = k[o] || [], h = h[2] && new RegExp("(^|\\.)" + p.join("\\.(?:.*\\.|)") + "(\\.|$)"), i = f = m.length;
                            while (f--) g = m[f], !e && q !== g.origType || c && c.guid !== g.guid || h && !h.test(g.namespace) || d && d !== g.selector && ("**" !== d || !g.selector) || (m.splice(f, 1), g.selector && m.delegateCount--, l.remove && l.remove.call(a, g));
                            i && !m.length && (l.teardown && l.teardown.call(a, p, r.handle) !== !1 || n.removeEvent(a, o, r.handle), delete k[o])
                        } else
                            for (o in k) n.event.remove(a, o + b[j], c, d, !0);
                    n.isEmptyObject(k) && (delete r.handle, n._removeData(a, "events"))
                }
            },
            trigger: function(b, c, d, e) {
                var f, g, h, i, k, l, m, o = [d || z],
                    p = j.call(b, "type") ? b.type : b,
                    q = j.call(b, "namespace") ? b.namespace.split(".") : [];
                if (h = l = d = d || z, 3 !== d.nodeType && 8 !== d.nodeType && !_.test(p + n.event.triggered) && (p.indexOf(".") >= 0 && (q = p.split("."), p = q.shift(), q.sort()), g = p.indexOf(":") < 0 && "on" + p, b = b[n.expando] ? b : new n.Event(p, "object" == typeof b && b), b.isTrigger = e ? 2 : 3, b.namespace = q.join("."), b.namespace_re = b.namespace ? new RegExp("(^|\\.)" + q.join("\\.(?:.*\\.|)") + "(\\.|$)") : null, b.result = void 0, b.target || (b.target = d), c = null == c ? [b] : n.makeArray(c, [b]), k = n.event.special[p] || {}, e || !k.trigger || k.trigger.apply(d, c) !== !1)) {
                    if (!e && !k.noBubble && !n.isWindow(d)) {
                        for (i = k.delegateType || p, _.test(i + p) || (h = h.parentNode); h; h = h.parentNode) o.push(h), l = h;
                        l === (d.ownerDocument || z) && o.push(l.defaultView || l.parentWindow || a)
                    }
                    m = 0;
                    while ((h = o[m++]) && !b.isPropagationStopped()) b.type = m > 1 ? i : k.bindType || p, f = (n._data(h, "events") || {})[b.type] && n._data(h, "handle"), f && f.apply(h, c), f = g && h[g], f && f.apply && n.acceptData(h) && (b.result = f.apply(h, c), b.result === !1 && b.preventDefault());
                    if (b.type = p, !e && !b.isDefaultPrevented() && (!k._default || k._default.apply(o.pop(), c) === !1) && n.acceptData(d) && g && d[p] && !n.isWindow(d)) {
                        l = d[g], l && (d[g] = null), n.event.triggered = p;
                        try {
                            d[p]()
                        } catch (r) {}
                        n.event.triggered = void 0, l && (d[g] = l)
                    }
                    return b.result
                }
            },
            dispatch: function(a) {
                a = n.event.fix(a);
                var b, c, e, f, g, h = [],
                    i = d.call(arguments),
                    j = (n._data(this, "events") || {})[a.type] || [],
                    k = n.event.special[a.type] || {};
                if (i[0] = a, a.delegateTarget = this, !k.preDispatch || k.preDispatch.call(this, a) !== !1) {
                    h = n.event.handlers.call(this, a, j), b = 0;
                    while ((f = h[b++]) && !a.isPropagationStopped()) {
                        a.currentTarget = f.elem, g = 0;
                        while ((e = f.handlers[g++]) && !a.isImmediatePropagationStopped())(!a.namespace_re || a.namespace_re.test(e.namespace)) && (a.handleObj = e, a.data = e.data, c = ((n.event.special[e.origType] || {}).handle || e.handler).apply(f.elem, i), void 0 !== c && (a.result = c) === !1 && (a.preventDefault(), a.stopPropagation()))
                    }
                    return k.postDispatch && k.postDispatch.call(this, a), a.result
                }
            },
            handlers: function(a, b) {
                var c, d, e, f, g = [],
                    h = b.delegateCount,
                    i = a.target;
                if (h && i.nodeType && (!a.button || "click" !== a.type))
                    for (; i != this; i = i.parentNode || this)
                        if (1 === i.nodeType && (i.disabled !== !0 || "click" !== a.type)) {
                            for (e = [], f = 0; h > f; f++) d = b[f], c = d.selector + " ", void 0 === e[c] && (e[c] = d.needsContext ? n(c, this).index(i) >= 0 : n.find(c, this, null, [i]).length), e[c] && e.push(d);
                            e.length && g.push({
                                elem: i,
                                handlers: e
                            })
                        }
                return h < b.length && g.push({
                    elem: this,
                    handlers: b.slice(h)
                }), g
            },
            fix: function(a) {
                if (a[n.expando]) return a;
                var b, c, d, e = a.type,
                    f = a,
                    g = this.fixHooks[e];
                g || (this.fixHooks[e] = g = $.test(e) ? this.mouseHooks : Z.test(e) ? this.keyHooks : {}), d = g.props ? this.props.concat(g.props) : this.props, a = new n.Event(f), b = d.length;
                while (b--) c = d[b], a[c] = f[c];
                return a.target || (a.target = f.srcElement || z), 3 === a.target.nodeType && (a.target = a.target.parentNode), a.metaKey = !!a.metaKey, g.filter ? g.filter(a, f) : a
            },
            props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
            fixHooks: {},
            keyHooks: {
                props: "char charCode key keyCode".split(" "),
                filter: function(a, b) {
                    return null == a.which && (a.which = null != b.charCode ? b.charCode : b.keyCode), a
                }
            },
            mouseHooks: {
                props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
                filter: function(a, b) {
                    var c, d, e, f = b.button,
                        g = b.fromElement;
                    return null == a.pageX && null != b.clientX && (d = a.target.ownerDocument || z, e = d.documentElement, c = d.body, a.pageX = b.clientX + (e && e.scrollLeft || c && c.scrollLeft || 0) - (e && e.clientLeft || c && c.clientLeft || 0), a.pageY = b.clientY + (e && e.scrollTop || c && c.scrollTop || 0) - (e && e.clientTop || c && c.clientTop || 0)), !a.relatedTarget && g && (a.relatedTarget = g === a.target ? b.toElement : g), a.which || void 0 === f || (a.which = 1 & f ? 1 : 2 & f ? 3 : 4 & f ? 2 : 0), a
                }
            },
            special: {
                load: {
                    noBubble: !0
                },
                focus: {
                    trigger: function() {
                        if (this !== db() && this.focus) try {
                            return this.focus(), !1
                        } catch (a) {}
                    },
                    delegateType: "focusin"
                },
                blur: {
                    trigger: function() {
                        return this === db() && this.blur ? (this.blur(), !1) : void 0
                    },
                    delegateType: "focusout"
                },
                click: {
                    trigger: function() {
                        return n.nodeName(this, "input") && "checkbox" === this.type && this.click ? (this.click(), !1) : void 0
                    },
                    _default: function(a) {
                        return n.nodeName(a.target, "a")
                    }
                },
                beforeunload: {
                    postDispatch: function(a) {
                        void 0 !== a.result && (a.originalEvent.returnValue = a.result)
                    }
                }
            },
            simulate: function(a, b, c, d) {
                var e = n.extend(new n.Event, c, {
                    type: a,
                    isSimulated: !0,
                    originalEvent: {}
                });
                d ? n.event.trigger(e, null, b) : n.event.dispatch.call(b, e), e.isDefaultPrevented() && c.preventDefault()
            }
        }, n.removeEvent = z.removeEventListener ? function(a, b, c) {
            a.removeEventListener && a.removeEventListener(b, c, !1)
        } : function(a, b, c) {
            var d = "on" + b;
            a.detachEvent && (typeof a[d] === L && (a[d] = null), a.detachEvent(d, c))
        }, n.Event = function(a, b) {
            return this instanceof n.Event ? (a && a.type ? (this.originalEvent = a, this.type = a.type, this.isDefaultPrevented = a.defaultPrevented || void 0 === a.defaultPrevented && (a.returnValue === !1 || a.getPreventDefault && a.getPreventDefault()) ? bb : cb) : this.type = a, b && n.extend(this, b), this.timeStamp = a && a.timeStamp || n.now(), void(this[n.expando] = !0)) : new n.Event(a, b)
        }, n.Event.prototype = {
            isDefaultPrevented: cb,
            isPropagationStopped: cb,
            isImmediatePropagationStopped: cb,
            preventDefault: function() {
                var a = this.originalEvent;
                this.isDefaultPrevented = bb, a && (a.preventDefault ? a.preventDefault() : a.returnValue = !1)
            },
            stopPropagation: function() {
                var a = this.originalEvent;
                this.isPropagationStopped = bb, a && (a.stopPropagation && a.stopPropagation(), a.cancelBubble = !0)
            },
            stopImmediatePropagation: function() {
                this.isImmediatePropagationStopped = bb, this.stopPropagation()
            }
        }, n.each({
            mouseenter: "mouseover",
            mouseleave: "mouseout"
        }, function(a, b) {
            n.event.special[a] = {
                delegateType: b,
                bindType: b,
                handle: function(a) {
                    var c, d = this,
                        e = a.relatedTarget,
                        f = a.handleObj;
                    return (!e || e !== d && !n.contains(d, e)) && (a.type = f.origType, c = f.handler.apply(this, arguments), a.type = b), c
                }
            }
        }), l.submitBubbles || (n.event.special.submit = {
            setup: function() {
                return n.nodeName(this, "form") ? !1 : void n.event.add(this, "click._submit keypress._submit", function(a) {
                    var b = a.target,
                        c = n.nodeName(b, "input") || n.nodeName(b, "button") ? b.form : void 0;
                    c && !n._data(c, "submitBubbles") && (n.event.add(c, "submit._submit", function(a) {
                        a._submit_bubble = !0
                    }), n._data(c, "submitBubbles", !0))
                })
            },
            postDispatch: function(a) {
                a._submit_bubble && (delete a._submit_bubble, this.parentNode && !a.isTrigger && n.event.simulate("submit", this.parentNode, a, !0))
            },
            teardown: function() {
                return n.nodeName(this, "form") ? !1 : void n.event.remove(this, "._submit")
            }
        }), l.changeBubbles || (n.event.special.change = {
            setup: function() {
                return Y.test(this.nodeName) ? (("checkbox" === this.type || "radio" === this.type) && (n.event.add(this, "propertychange._change", function(a) {
                    "checked" === a.originalEvent.propertyName && (this._just_changed = !0)
                }), n.event.add(this, "click._change", function(a) {
                    this._just_changed && !a.isTrigger && (this._just_changed = !1), n.event.simulate("change", this, a, !0)
                })), !1) : void n.event.add(this, "beforeactivate._change", function(a) {
                    var b = a.target;
                    Y.test(b.nodeName) && !n._data(b, "changeBubbles") && (n.event.add(b, "change._change", function(a) {
                        !this.parentNode || a.isSimulated || a.isTrigger || n.event.simulate("change", this.parentNode, a, !0)
                    }), n._data(b, "changeBubbles", !0))
                })
            },
            handle: function(a) {
                var b = a.target;
                return this !== b || a.isSimulated || a.isTrigger || "radio" !== b.type && "checkbox" !== b.type ? a.handleObj.handler.apply(this, arguments) : void 0
            },
            teardown: function() {
                return n.event.remove(this, "._change"), !Y.test(this.nodeName)
            }
        }), l.focusinBubbles || n.each({
            focus: "focusin",
            blur: "focusout"
        }, function(a, b) {
            var c = function(a) {
                n.event.simulate(b, a.target, n.event.fix(a), !0)
            };
            n.event.special[b] = {
                setup: function() {
                    var d = this.ownerDocument || this,
                        e = n._data(d, b);
                    e || d.addEventListener(a, c, !0), n._data(d, b, (e || 0) + 1)
                },
                teardown: function() {
                    var d = this.ownerDocument || this,
                        e = n._data(d, b) - 1;
                    e ? n._data(d, b, e) : (d.removeEventListener(a, c, !0), n._removeData(d, b))
                }
            }
        }), n.fn.extend({
            on: function(a, b, c, d, e) {
                var f, g;
                if ("object" == typeof a) {
                    "string" != typeof b && (c = c || b, b = void 0);
                    for (f in a) this.on(f, b, c, a[f], e);
                    return this
                }
                if (null == c && null == d ? (d = b, c = b = void 0) : null == d && ("string" == typeof b ? (d = c, c = void 0) : (d = c, c = b, b = void 0)), d === !1) d = cb;
                else if (!d) return this;
                return 1 === e && (g = d, d = function(a) {
                    return n().off(a), g.apply(this, arguments)
                }, d.guid = g.guid || (g.guid = n.guid++)), this.each(function() {
                    n.event.add(this, a, d, c, b)
                })
            },
            one: function(a, b, c, d) {
                return this.on(a, b, c, d, 1)
            },
            off: function(a, b, c) {
                var d, e;
                if (a && a.preventDefault && a.handleObj) return d = a.handleObj, n(a.delegateTarget).off(d.namespace ? d.origType + "." + d.namespace : d.origType, d.selector, d.handler), this;
                if ("object" == typeof a) {
                    for (e in a) this.off(e, b, a[e]);
                    return this
                }
                return (b === !1 || "function" == typeof b) && (c = b, b = void 0), c === !1 && (c = cb), this.each(function() {
                    n.event.remove(this, a, c, b)
                })
            },
            trigger: function(a, b) {
                return this.each(function() {
                    n.event.trigger(a, b, this)
                })
            },
            triggerHandler: function(a, b) {
                var c = this[0];
                return c ? n.event.trigger(a, b, c, !0) : void 0
            }
        });
    
        function eb(a) {
            var b = fb.split("|"),
                c = a.createDocumentFragment();
            if (c.createElement)
                while (b.length) c.createElement(b.pop());
            return c
        }
        var fb = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
            gb = / jQuery\d+="(?:null|\d+)"/g,
            hb = new RegExp("<(?:" + fb + ")[\\s/>]", "i"),
            ib = /^\s+/,
            jb = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
            kb = /<([\w:]+)/,
            lb = /<tbody/i,
            mb = /<|&#?\w+;/,
            nb = /<(?:script|style|link)/i,
            ob = /checked\s*(?:[^=]|=\s*.checked.)/i,
            pb = /^$|\/(?:java|ecma)script/i,
            qb = /^true\/(.*)/,
            rb = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
            sb = {
                option: [1, "<select multiple='multiple'>", "</select>"],
                legend: [1, "<fieldset>", "</fieldset>"],
                area: [1, "<map>", "</map>"],
                param: [1, "<object>", "</object>"],
                thead: [1, "<table>", "</table>"],
                tr: [2, "<table><tbody>", "</tbody></table>"],
                col: [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"],
                td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
                _default: l.htmlSerialize ? [0, "", ""] : [1, "X<div>", "</div>"]
            },
            tb = eb(z),
            ub = tb.appendChild(z.createElement("div"));
        sb.optgroup = sb.option, sb.tbody = sb.tfoot = sb.colgroup = sb.caption = sb.thead, sb.th = sb.td;
    
        function vb(a, b) {
            var c, d, e = 0,
                f = typeof a.getElementsByTagName !== L ? a.getElementsByTagName(b || "*") : typeof a.querySelectorAll !== L ? a.querySelectorAll(b || "*") : void 0;
            if (!f)
                for (f = [], c = a.childNodes || a; null != (d = c[e]); e++) !b || n.nodeName(d, b) ? f.push(d) : n.merge(f, vb(d, b));
            return void 0 === b || b && n.nodeName(a, b) ? n.merge([a], f) : f
        }
    
        function wb(a) {
            X.test(a.type) && (a.defaultChecked = a.checked)
        }
    
        function xb(a, b) {
            return n.nodeName(a, "table") && n.nodeName(11 !== b.nodeType ? b : b.firstChild, "tr") ? a.getElementsByTagName("tbody")[0] || a.appendChild(a.ownerDocument.createElement("tbody")) : a
        }
    
        function yb(a) {
            return a.type = (null !== n.find.attr(a, "type")) + "/" + a.type, a
        }
    
        function zb(a) {
            var b = qb.exec(a.type);
            return b ? a.type = b[1] : a.removeAttribute("type"), a
        }
    
        function Ab(a, b) {
            for (var c, d = 0; null != (c = a[d]); d++) n._data(c, "globalEval", !b || n._data(b[d], "globalEval"))
        }
    
        function Bb(a, b) {
            if (1 === b.nodeType && n.hasData(a)) {
                var c, d, e, f = n._data(a),
                    g = n._data(b, f),
                    h = f.events;
                if (h) {
                    delete g.handle, g.events = {};
                    for (c in h)
                        for (d = 0, e = h[c].length; e > d; d++) n.event.add(b, c, h[c][d])
                }
                g.data && (g.data = n.extend({}, g.data))
            }
        }
    
        function Cb(a, b) {
            var c, d, e;
            if (1 === b.nodeType) {
                if (c = b.nodeName.toLowerCase(), !l.noCloneEvent && b[n.expando]) {
                    e = n._data(b);
                    for (d in e.events) n.removeEvent(b, d, e.handle);
                    b.removeAttribute(n.expando)
                }
                "script" === c && b.text !== a.text ? (yb(b).text = a.text, zb(b)) : "object" === c ? (b.parentNode && (b.outerHTML = a.outerHTML), l.html5Clone && a.innerHTML && !n.trim(b.innerHTML) && (b.innerHTML = a.innerHTML)) : "input" === c && X.test(a.type) ? (b.defaultChecked = b.checked = a.checked, b.value !== a.value && (b.value = a.value)) : "option" === c ? b.defaultSelected = b.selected = a.defaultSelected : ("input" === c || "textarea" === c) && (b.defaultValue = a.defaultValue)
            }
        }
        n.extend({
            clone: function(a, b, c) {
                var d, e, f, g, h, i = n.contains(a.ownerDocument, a);
                if (l.html5Clone || n.isXMLDoc(a) || !hb.test("<" + a.nodeName + ">") ? f = a.cloneNode(!0) : (ub.innerHTML = a.outerHTML, ub.removeChild(f = ub.firstChild)), !(l.noCloneEvent && l.noCloneChecked || 1 !== a.nodeType && 11 !== a.nodeType || n.isXMLDoc(a)))
                    for (d = vb(f), h = vb(a), g = 0; null != (e = h[g]); ++g) d[g] && Cb(e, d[g]);
                if (b)
                    if (c)
                        for (h = h || vb(a), d = d || vb(f), g = 0; null != (e = h[g]); g++) Bb(e, d[g]);
                    else Bb(a, f);
                return d = vb(f, "script"), d.length > 0 && Ab(d, !i && vb(a, "script")), d = h = e = null, f
            },
            buildFragment: function(a, b, c, d) {
                for (var e, f, g, h, i, j, k, m = a.length, o = eb(b), p = [], q = 0; m > q; q++)
                    if (f = a[q], f || 0 === f)
                        if ("object" === n.type(f)) n.merge(p, f.nodeType ? [f] : f);
                        else if (mb.test(f)) {
                    h = h || o.appendChild(b.createElement("div")), i = (kb.exec(f) || ["", ""])[1].toLowerCase(), k = sb[i] || sb._default, h.innerHTML = k[1] + f.replace(jb, "<$1></$2>") + k[2], e = k[0];
                    while (e--) h = h.lastChild;
                    if (!l.leadingWhitespace && ib.test(f) && p.push(b.createTextNode(ib.exec(f)[0])), !l.tbody) {
                        f = "table" !== i || lb.test(f) ? "<table>" !== k[1] || lb.test(f) ? 0 : h : h.firstChild, e = f && f.childNodes.length;
                        while (e--) n.nodeName(j = f.childNodes[e], "tbody") && !j.childNodes.length && f.removeChild(j)
                    }
                    n.merge(p, h.childNodes), h.textContent = "";
                    while (h.firstChild) h.removeChild(h.firstChild);
                    h = o.lastChild
                } else p.push(b.createTextNode(f));
                h && o.removeChild(h), l.appendChecked || n.grep(vb(p, "input"), wb), q = 0;
                while (f = p[q++])
                    if ((!d || -1 === n.inArray(f, d)) && (g = n.contains(f.ownerDocument, f), h = vb(o.appendChild(f), "script"), g && Ab(h), c)) {
                        e = 0;
                        while (f = h[e++]) pb.test(f.type || "") && c.push(f)
                    }
                return h = null, o
            },
            cleanData: function(a, b) {
                for (var d, e, f, g, h = 0, i = n.expando, j = n.cache, k = l.deleteExpando, m = n.event.special; null != (d = a[h]); h++)
                    if ((b || n.acceptData(d)) && (f = d[i], g = f && j[f])) {
                        if (g.events)
                            for (e in g.events) m[e] ? n.event.remove(d, e) : n.removeEvent(d, e, g.handle);
                        j[f] && (delete j[f], k ? delete d[i] : typeof d.removeAttribute !== L ? d.removeAttribute(i) : d[i] = null, c.push(f))
                    }
            }
        }), n.fn.extend({
            text: function(a) {
                return W(this, function(a) {
                    return void 0 === a ? n.text(this) : this.empty().append((this[0] && this[0].ownerDocument || z).createTextNode(a))
                }, null, a, arguments.length)
            },
            append: function() {
                return this.domManip(arguments, function(a) {
                    if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) {
                        var b = xb(this, a);
                        b.appendChild(a)
                    }
                })
            },
            prepend: function() {
                return this.domManip(arguments, function(a) {
                    if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) {
                        var b = xb(this, a);
                        b.insertBefore(a, b.firstChild)
                    }
                })
            },
            before: function() {
                return this.domManip(arguments, function(a) {
                    this.parentNode && this.parentNode.insertBefore(a, this)
                })
            },
            after: function() {
                return this.domManip(arguments, function(a) {
                    this.parentNode && this.parentNode.insertBefore(a, this.nextSibling)
                })
            },
            remove: function(a, b) {
                for (var c, d = a ? n.filter(a, this) : this, e = 0; null != (c = d[e]); e++) b || 1 !== c.nodeType || n.cleanData(vb(c)), c.parentNode && (b && n.contains(c.ownerDocument, c) && Ab(vb(c, "script")), c.parentNode.removeChild(c));
                return this
            },
            empty: function() {
                for (var a, b = 0; null != (a = this[b]); b++) {
                    1 === a.nodeType && n.cleanData(vb(a, !1));
                    while (a.firstChild) a.removeChild(a.firstChild);
                    a.options && n.nodeName(a, "select") && (a.options.length = 0)
                }
                return this
            },
            clone: function(a, b) {
                return a = null == a ? !1 : a, b = null == b ? a : b, this.map(function() {
                    return n.clone(this, a, b)
                })
            },
            html: function(a) {
                return W(this, function(a) {
                    var b = this[0] || {},
                        c = 0,
                        d = this.length;
                    if (void 0 === a) return 1 === b.nodeType ? b.innerHTML.replace(gb, "") : void 0;
                    if (!("string" != typeof a || nb.test(a) || !l.htmlSerialize && hb.test(a) || !l.leadingWhitespace && ib.test(a) || sb[(kb.exec(a) || ["", ""])[1].toLowerCase()])) {
                        a = a.replace(jb, "<$1></$2>");
                        try {
                            for (; d > c; c++) b = this[c] || {}, 1 === b.nodeType && (n.cleanData(vb(b, !1)), b.innerHTML = a);
                            b = 0
                        } catch (e) {}
                    }
                    b && this.empty().append(a)
                }, null, a, arguments.length)
            },
            replaceWith: function() {
                var a = arguments[0];
                return this.domManip(arguments, function(b) {
                    a = this.parentNode, n.cleanData(vb(this)), a && a.replaceChild(b, this)
                }), a && (a.length || a.nodeType) ? this : this.remove()
            },
            detach: function(a) {
                return this.remove(a, !0)
            },
            domManip: function(a, b) {
                a = e.apply([], a);
                var c, d, f, g, h, i, j = 0,
                    k = this.length,
                    m = this,
                    o = k - 1,
                    p = a[0],
                    q = n.isFunction(p);
                if (q || k > 1 && "string" == typeof p && !l.checkClone && ob.test(p)) return this.each(function(c) {
                    var d = m.eq(c);
                    q && (a[0] = p.call(this, c, d.html())), d.domManip(a, b)
                });
                if (k && (i = n.buildFragment(a, this[0].ownerDocument, !1, this), c = i.firstChild, 1 === i.childNodes.length && (i = c), c)) {
                    for (g = n.map(vb(i, "script"), yb), f = g.length; k > j; j++) d = i, j !== o && (d = n.clone(d, !0, !0), f && n.merge(g, vb(d, "script"))), b.call(this[j], d, j);
                    if (f)
                        for (h = g[g.length - 1].ownerDocument, n.map(g, zb), j = 0; f > j; j++) d = g[j], pb.test(d.type || "") && !n._data(d, "globalEval") && n.contains(h, d) && (d.src ? n._evalUrl && n._evalUrl(d.src) : n.globalEval((d.text || d.textContent || d.innerHTML || "").replace(rb, "")));
                    i = c = null
                }
                return this
            }
        }), n.each({
            appendTo: "append",
            prependTo: "prepend",
            insertBefore: "before",
            insertAfter: "after",
            replaceAll: "replaceWith"
        }, function(a, b) {
            n.fn[a] = function(a) {
                for (var c, d = 0, e = [], g = n(a), h = g.length - 1; h >= d; d++) c = d === h ? this : this.clone(!0), n(g[d])[b](c), f.apply(e, c.get());
                return this.pushStack(e)
            }
        });
        var Db, Eb = {};
    
        function Fb(b, c) {
            var d = n(c.createElement(b)).appendTo(c.body),
                e = a.getDefaultComputedStyle ? a.getDefaultComputedStyle(d[0]).display : n.css(d[0], "display");
            return d.detach(), e
        }
    
        function Gb(a) {
            var b = z,
                c = Eb[a];
            return c || (c = Fb(a, b), "none" !== c && c || (Db = (Db || n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement), b = (Db[0].contentWindow || Db[0].contentDocument).document, b.write(), b.close(), c = Fb(a, b), Db.detach()), Eb[a] = c), c
        }! function() {
            var a, b, c = z.createElement("div"),
                d = "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";
            c.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>", a = c.getElementsByTagName("a")[0], a.style.cssText = "float:left;opacity:.5", l.opacity = /^0.5/.test(a.style.opacity), l.cssFloat = !!a.style.cssFloat, c.style.backgroundClip = "content-box", c.cloneNode(!0).style.backgroundClip = "", l.clearCloneStyle = "content-box" === c.style.backgroundClip, a = c = null, l.shrinkWrapBlocks = function() {
                var a, c, e, f;
                if (null == b) {
                    if (a = z.getElementsByTagName("body")[0], !a) return;
                    f = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px", c = z.createElement("div"), e = z.createElement("div"), a.appendChild(c).appendChild(e), b = !1, typeof e.style.zoom !== L && (e.style.cssText = d + ";width:1px;padding:1px;zoom:1", e.innerHTML = "<div></div>", e.firstChild.style.width = "5px", b = 3 !== e.offsetWidth), a.removeChild(c), a = c = e = null
                }
                return b
            }
        }();
        var Hb = /^margin/,
            Ib = new RegExp("^(" + T + ")(?!px)[a-z%]+$", "i"),
            Jb, Kb, Lb = /^(top|right|bottom|left)$/;
        a.getComputedStyle ? (Jb = function(a) {
            return a.ownerDocument.defaultView.getComputedStyle(a, null)
        }, Kb = function(a, b, c) {
            var d, e, f, g, h = a.style;
            return c = c || Jb(a), g = c ? c.getPropertyValue(b) || c[b] : void 0, c && ("" !== g || n.contains(a.ownerDocument, a) || (g = n.style(a, b)), Ib.test(g) && Hb.test(b) && (d = h.width, e = h.minWidth, f = h.maxWidth, h.minWidth = h.maxWidth = h.width = g, g = c.width, h.width = d, h.minWidth = e, h.maxWidth = f)), void 0 === g ? g : g + ""
        }) : z.documentElement.currentStyle && (Jb = function(a) {
            return a.currentStyle
        }, Kb = function(a, b, c) {
            var d, e, f, g, h = a.style;
            return c = c || Jb(a), g = c ? c[b] : void 0, null == g && h && h[b] && (g = h[b]), Ib.test(g) && !Lb.test(b) && (d = h.left, e = a.runtimeStyle, f = e && e.left, f && (e.left = a.currentStyle.left), h.left = "fontSize" === b ? "1em" : g, g = h.pixelLeft + "px", h.left = d, f && (e.left = f)), void 0 === g ? g : g + "" || "auto"
        });
    
        function Mb(a, b) {
            return {
                get: function() {
                    var c = a();
                    if (null != c) return c ? void delete this.get : (this.get = b).apply(this, arguments)
                }
            }
        }! function() {
            var b, c, d, e, f, g, h = z.createElement("div"),
                i = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px",
                j = "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";
            h.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>", b = h.getElementsByTagName("a")[0], b.style.cssText = "float:left;opacity:.5", l.opacity = /^0.5/.test(b.style.opacity), l.cssFloat = !!b.style.cssFloat, h.style.backgroundClip = "content-box", h.cloneNode(!0).style.backgroundClip = "", l.clearCloneStyle = "content-box" === h.style.backgroundClip, b = h = null, n.extend(l, {
                reliableHiddenOffsets: function() {
                    if (null != c) return c;
                    var a, b, d, e = z.createElement("div"),
                        f = z.getElementsByTagName("body")[0];
                    if (f) return e.setAttribute("className", "t"), e.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>", a = z.createElement("div"), a.style.cssText = i, f.appendChild(a).appendChild(e), e.innerHTML = "<table><tr><td></td><td>t</td></tr></table>", b = e.getElementsByTagName("td"), b[0].style.cssText = "padding:0;margin:0;border:0;display:none", d = 0 === b[0].offsetHeight, b[0].style.display = "", b[1].style.display = "none", c = d && 0 === b[0].offsetHeight, f.removeChild(a), e = f = null, c
                },
                boxSizing: function() {
                    return null == d && k(), d
                },
                boxSizingReliable: function() {
                    return null == e && k(), e
                },
                pixelPosition: function() {
                    return null == f && k(), f
                },
                reliableMarginRight: function() {
                    var b, c, d, e;
                    if (null == g && a.getComputedStyle) {
                        if (b = z.getElementsByTagName("body")[0], !b) return;
                        c = z.createElement("div"), d = z.createElement("div"), c.style.cssText = i, b.appendChild(c).appendChild(d), e = d.appendChild(z.createElement("div")), e.style.cssText = d.style.cssText = j, e.style.marginRight = e.style.width = "0", d.style.width = "1px", g = !parseFloat((a.getComputedStyle(e, null) || {}).marginRight), b.removeChild(c)
                    }
                    return g
                }
            });
    
            function k() {
                var b, c, h = z.getElementsByTagName("body")[0];
                h && (b = z.createElement("div"), c = z.createElement("div"), b.style.cssText = i, h.appendChild(b).appendChild(c), c.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;display:block;padding:1px;border:1px;width:4px;margin-top:1%;top:1%", n.swap(h, null != h.style.zoom ? {
                    zoom: 1
                } : {}, function() {
                    d = 4 === c.offsetWidth
                }), e = !0, f = !1, g = !0, a.getComputedStyle && (f = "1%" !== (a.getComputedStyle(c, null) || {}).top, e = "4px" === (a.getComputedStyle(c, null) || {
                    width: "4px"
                }).width), h.removeChild(b), c = h = null)
            }
        }(), n.swap = function(a, b, c, d) {
            var e, f, g = {};
            for (f in b) g[f] = a.style[f], a.style[f] = b[f];
            e = c.apply(a, d || []);
            for (f in b) a.style[f] = g[f];
            return e
        };
        var Nb = /alpha\([^)]*\)/i,
            Ob = /opacity\s*=\s*([^)]*)/,
            Pb = /^(none|table(?!-c[ea]).+)/,
            Qb = new RegExp("^(" + T + ")(.*)$", "i"),
            Rb = new RegExp("^([+-])=(" + T + ")", "i"),
            Sb = {
                position: "absolute",
                visibility: "hidden",
                display: "block"
            },
            Tb = {
                letterSpacing: 0,
                fontWeight: 400
            },
            Ub = ["Webkit", "O", "Moz", "ms"];
    
        function Vb(a, b) {
            if (b in a) return b;
            var c = b.charAt(0).toUpperCase() + b.slice(1),
                d = b,
                e = Ub.length;
            while (e--)
                if (b = Ub[e] + c, b in a) return b;
            return d
        }
    
        function Wb(a, b) {
            for (var c, d, e, f = [], g = 0, h = a.length; h > g; g++) d = a[g], d.style && (f[g] = n._data(d, "olddisplay"), c = d.style.display, b ? (f[g] || "none" !== c || (d.style.display = ""), "" === d.style.display && V(d) && (f[g] = n._data(d, "olddisplay", Gb(d.nodeName)))) : f[g] || (e = V(d), (c && "none" !== c || !e) && n._data(d, "olddisplay", e ? c : n.css(d, "display"))));
            for (g = 0; h > g; g++) d = a[g], d.style && (b && "none" !== d.style.display && "" !== d.style.display || (d.style.display = b ? f[g] || "" : "none"));
            return a
        }
    
        function Xb(a, b, c) {
            var d = Qb.exec(b);
            return d ? Math.max(0, d[1] - (c || 0)) + (d[2] || "px") : b
        }
    
        function Yb(a, b, c, d, e) {
            for (var f = c === (d ? "border" : "content") ? 4 : "width" === b ? 1 : 0, g = 0; 4 > f; f += 2) "margin" === c && (g += n.css(a, c + U[f], !0, e)), d ? ("content" === c && (g -= n.css(a, "padding" + U[f], !0, e)), "margin" !== c && (g -= n.css(a, "border" + U[f] + "Width", !0, e))) : (g += n.css(a, "padding" + U[f], !0, e), "padding" !== c && (g += n.css(a, "border" + U[f] + "Width", !0, e)));
            return g
        }
    
        function Zb(a, b, c) {
            var d = !0,
                e = "width" === b ? a.offsetWidth : a.offsetHeight,
                f = Jb(a),
                g = l.boxSizing() && "border-box" === n.css(a, "boxSizing", !1, f);
            if (0 >= e || null == e) {
                if (e = Kb(a, b, f), (0 > e || null == e) && (e = a.style[b]), Ib.test(e)) return e;
                d = g && (l.boxSizingReliable() || e === a.style[b]), e = parseFloat(e) || 0
            }
            return e + Yb(a, b, c || (g ? "border" : "content"), d, f) + "px"
        }
        n.extend({
            cssHooks: {
                opacity: {
                    get: function(a, b) {
                        if (b) {
                            var c = Kb(a, "opacity");
                            return "" === c ? "1" : c
                        }
                    }
                }
            },
            cssNumber: {
                columnCount: !0,
                fillOpacity: !0,
                fontWeight: !0,
                lineHeight: !0,
                opacity: !0,
                order: !0,
                orphans: !0,
                widows: !0,
                zIndex: !0,
                zoom: !0
            },
            cssProps: {
                "float": l.cssFloat ? "cssFloat" : "styleFloat"
            },
            style: function(a, b, c, d) {
                if (a && 3 !== a.nodeType && 8 !== a.nodeType && a.style) {
                    var e, f, g, h = n.camelCase(b),
                        i = a.style;
                    if (b = n.cssProps[h] || (n.cssProps[h] = Vb(i, h)), g = n.cssHooks[b] || n.cssHooks[h], void 0 === c) return g && "get" in g && void 0 !== (e = g.get(a, !1, d)) ? e : i[b];
                    if (f = typeof c, "string" === f && (e = Rb.exec(c)) && (c = (e[1] + 1) * e[2] + parseFloat(n.css(a, b)), f = "number"), null != c && c === c && ("number" !== f || n.cssNumber[h] || (c += "px"), l.clearCloneStyle || "" !== c || 0 !== b.indexOf("background") || (i[b] = "inherit"), !(g && "set" in g && void 0 === (c = g.set(a, c, d))))) try {
                        i[b] = "", i[b] = c
                    } catch (j) {}
                }
            },
            css: function(a, b, c, d) {
                var e, f, g, h = n.camelCase(b);
                return b = n.cssProps[h] || (n.cssProps[h] = Vb(a.style, h)), g = n.cssHooks[b] || n.cssHooks[h], g && "get" in g && (f = g.get(a, !0, c)), void 0 === f && (f = Kb(a, b, d)), "normal" === f && b in Tb && (f = Tb[b]), "" === c || c ? (e = parseFloat(f), c === !0 || n.isNumeric(e) ? e || 0 : f) : f
            }
        }), n.each(["height", "width"], function(a, b) {
            n.cssHooks[b] = {
                get: function(a, c, d) {
                    return c ? 0 === a.offsetWidth && Pb.test(n.css(a, "display")) ? n.swap(a, Sb, function() {
                        return Zb(a, b, d)
                    }) : Zb(a, b, d) : void 0
                },
                set: function(a, c, d) {
                    var e = d && Jb(a);
                    return Xb(a, c, d ? Yb(a, b, d, l.boxSizing() && "border-box" === n.css(a, "boxSizing", !1, e), e) : 0)
                }
            }
        }), l.opacity || (n.cssHooks.opacity = {
            get: function(a, b) {
                return Ob.test((b && a.currentStyle ? a.currentStyle.filter : a.style.filter) || "") ? .01 * parseFloat(RegExp.$1) + "" : b ? "1" : ""
            },
            set: function(a, b) {
                var c = a.style,
                    d = a.currentStyle,
                    e = n.isNumeric(b) ? "alpha(opacity=" + 100 * b + ")" : "",
                    f = d && d.filter || c.filter || "";
                c.zoom = 1, (b >= 1 || "" === b) && "" === n.trim(f.replace(Nb, "")) && c.removeAttribute && (c.removeAttribute("filter"), "" === b || d && !d.filter) || (c.filter = Nb.test(f) ? f.replace(Nb, e) : f + " " + e)
            }
        }), n.cssHooks.marginRight = Mb(l.reliableMarginRight, function(a, b) {
            return b ? n.swap(a, {
                display: "inline-block"
            }, Kb, [a, "marginRight"]) : void 0
        }), n.each({
            margin: "",
            padding: "",
            border: "Width"
        }, function(a, b) {
            n.cssHooks[a + b] = {
                expand: function(c) {
                    for (var d = 0, e = {}, f = "string" == typeof c ? c.split(" ") : [c]; 4 > d; d++) e[a + U[d] + b] = f[d] || f[d - 2] || f[0];
                    return e
                }
            }, Hb.test(a) || (n.cssHooks[a + b].set = Xb)
        }), n.fn.extend({
            css: function(a, b) {
                return W(this, function(a, b, c) {
                    var d, e, f = {},
                        g = 0;
                    if (n.isArray(b)) {
                        for (d = Jb(a), e = b.length; e > g; g++) f[b[g]] = n.css(a, b[g], !1, d);
                        return f
                    }
                    return void 0 !== c ? n.style(a, b, c) : n.css(a, b)
                }, a, b, arguments.length > 1)
            },
            show: function() {
                return Wb(this, !0)
            },
            hide: function() {
                return Wb(this)
            },
            toggle: function(a) {
                return "boolean" == typeof a ? a ? this.show() : this.hide() : this.each(function() {
                    V(this) ? n(this).show() : n(this).hide()
                })
            }
        });
    
        function $b(a, b, c, d, e) {
            return new $b.prototype.init(a, b, c, d, e)
        }
        n.Tween = $b, $b.prototype = {
            constructor: $b,
            init: function(a, b, c, d, e, f) {
                this.elem = a, this.prop = c, this.easing = e || "swing", this.options = b, this.start = this.now = this.cur(), this.end = d, this.unit = f || (n.cssNumber[c] ? "" : "px")
            },
            cur: function() {
                var a = $b.propHooks[this.prop];
                return a && a.get ? a.get(this) : $b.propHooks._default.get(this)
            },
            run: function(a) {
                var b, c = $b.propHooks[this.prop];
                return this.pos = b = this.options.duration ? n.easing[this.easing](a, this.options.duration * a, 0, 1, this.options.duration) : a, this.now = (this.end - this.start) * b + this.start, this.options.step && this.options.step.call(this.elem, this.now, this), c && c.set ? c.set(this) : $b.propHooks._default.set(this), this
            }
        }, $b.prototype.init.prototype = $b.prototype, $b.propHooks = {
            _default: {
                get: function(a) {
                    var b;
                    return null == a.elem[a.prop] || a.elem.style && null != a.elem.style[a.prop] ? (b = n.css(a.elem, a.prop, ""), b && "auto" !== b ? b : 0) : a.elem[a.prop]
                },
                set: function(a) {
                    n.fx.step[a.prop] ? n.fx.step[a.prop](a) : a.elem.style && (null != a.elem.style[n.cssProps[a.prop]] || n.cssHooks[a.prop]) ? n.style(a.elem, a.prop, a.now + a.unit) : a.elem[a.prop] = a.now
                }
            }
        }, $b.propHooks.scrollTop = $b.propHooks.scrollLeft = {
            set: function(a) {
                a.elem.nodeType && a.elem.parentNode && (a.elem[a.prop] = a.now)
            }
        }, n.easing = {
            linear: function(a) {
                return a
            },
            swing: function(a) {
                return .5 - Math.cos(a * Math.PI) / 2
            }
        }, n.fx = $b.prototype.init, n.fx.step = {};
        var _b, ac, bc = /^(?:toggle|show|hide)$/,
            cc = new RegExp("^(?:([+-])=|)(" + T + ")([a-z%]*)$", "i"),
            dc = /queueHooks$/,
            ec = [jc],
            fc = {
                "*": [function(a, b) {
                    var c = this.createTween(a, b),
                        d = c.cur(),
                        e = cc.exec(b),
                        f = e && e[3] || (n.cssNumber[a] ? "" : "px"),
                        g = (n.cssNumber[a] || "px" !== f && +d) && cc.exec(n.css(c.elem, a)),
                        h = 1,
                        i = 20;
                    if (g && g[3] !== f) {
                        f = f || g[3], e = e || [], g = +d || 1;
                        do h = h || ".5", g /= h, n.style(c.elem, a, g + f); while (h !== (h = c.cur() / d) && 1 !== h && --i)
                    }
                    return e && (g = c.start = +g || +d || 0, c.unit = f, c.end = e[1] ? g + (e[1] + 1) * e[2] : +e[2]), c
                }]
            };
    
        function gc() {
            return setTimeout(function() {
                _b = void 0
            }), _b = n.now()
        }
    
        function hc(a, b) {
            var c, d = {
                    height: a
                },
                e = 0;
            for (b = b ? 1 : 0; 4 > e; e += 2 - b) c = U[e], d["margin" + c] = d["padding" + c] = a;
            return b && (d.opacity = d.width = a), d
        }
    
        function ic(a, b, c) {
            for (var d, e = (fc[b] || []).concat(fc["*"]), f = 0, g = e.length; g > f; f++)
                if (d = e[f].call(c, b, a)) return d
        }
    
        function jc(a, b, c) {
            var d, e, f, g, h, i, j, k, m = this,
                o = {},
                p = a.style,
                q = a.nodeType && V(a),
                r = n._data(a, "fxshow");
            c.queue || (h = n._queueHooks(a, "fx"), null == h.unqueued && (h.unqueued = 0, i = h.empty.fire, h.empty.fire = function() {
                h.unqueued || i()
            }), h.unqueued++, m.always(function() {
                m.always(function() {
                    h.unqueued--, n.queue(a, "fx").length || h.empty.fire()
                })
            })), 1 === a.nodeType && ("height" in b || "width" in b) && (c.overflow = [p.overflow, p.overflowX, p.overflowY], j = n.css(a, "display"), k = Gb(a.nodeName), "none" === j && (j = k), "inline" === j && "none" === n.css(a, "float") && (l.inlineBlockNeedsLayout && "inline" !== k ? p.zoom = 1 : p.display = "inline-block")), c.overflow && (p.overflow = "hidden", l.shrinkWrapBlocks() || m.always(function() {
                p.overflow = c.overflow[0], p.overflowX = c.overflow[1], p.overflowY = c.overflow[2]
            }));
            for (d in b)
                if (e = b[d], bc.exec(e)) {
                    if (delete b[d], f = f || "toggle" === e, e === (q ? "hide" : "show")) {
                        if ("show" !== e || !r || void 0 === r[d]) continue;
                        q = !0
                    }
                    o[d] = r && r[d] || n.style(a, d)
                }
            if (!n.isEmptyObject(o)) {
                r ? "hidden" in r && (q = r.hidden) : r = n._data(a, "fxshow", {}), f && (r.hidden = !q), q ? n(a).show() : m.done(function() {
                    n(a).hide()
                }), m.done(function() {
                    var b;
                    n._removeData(a, "fxshow");
                    for (b in o) n.style(a, b, o[b])
                });
                for (d in o) g = ic(q ? r[d] : 0, d, m), d in r || (r[d] = g.start, q && (g.end = g.start, g.start = "width" === d || "height" === d ? 1 : 0))
            }
        }
    
        function kc(a, b) {
            var c, d, e, f, g;
            for (c in a)
                if (d = n.camelCase(c), e = b[d], f = a[c], n.isArray(f) && (e = f[1], f = a[c] = f[0]), c !== d && (a[d] = f, delete a[c]), g = n.cssHooks[d], g && "expand" in g) {
                    f = g.expand(f), delete a[d];
                    for (c in f) c in a || (a[c] = f[c], b[c] = e)
                } else b[d] = e
        }
    
        function lc(a, b, c) {
            var d, e, f = 0,
                g = ec.length,
                h = n.Deferred().always(function() {
                    delete i.elem
                }),
                i = function() {
                    if (e) return !1;
                    for (var b = _b || gc(), c = Math.max(0, j.startTime + j.duration - b), d = c / j.duration || 0, f = 1 - d, g = 0, i = j.tweens.length; i > g; g++) j.tweens[g].run(f);
                    return h.notifyWith(a, [j, f, c]), 1 > f && i ? c : (h.resolveWith(a, [j]), !1)
                },
                j = h.promise({
                    elem: a,
                    props: n.extend({}, b),
                    opts: n.extend(!0, {
                        specialEasing: {}
                    }, c),
                    originalProperties: b,
                    originalOptions: c,
                    startTime: _b || gc(),
                    duration: c.duration,
                    tweens: [],
                    createTween: function(b, c) {
                        var d = n.Tween(a, j.opts, b, c, j.opts.specialEasing[b] || j.opts.easing);
                        return j.tweens.push(d), d
                    },
                    stop: function(b) {
                        var c = 0,
                            d = b ? j.tweens.length : 0;
                        if (e) return this;
                        for (e = !0; d > c; c++) j.tweens[c].run(1);
                        return b ? h.resolveWith(a, [j, b]) : h.rejectWith(a, [j, b]), this
                    }
                }),
                k = j.props;
            for (kc(k, j.opts.specialEasing); g > f; f++)
                if (d = ec[f].call(j, a, k, j.opts)) return d;
            return n.map(k, ic, j), n.isFunction(j.opts.start) && j.opts.start.call(a, j), n.fx.timer(n.extend(i, {
                elem: a,
                anim: j,
                queue: j.opts.queue
            })), j.progress(j.opts.progress).done(j.opts.done, j.opts.complete).fail(j.opts.fail).always(j.opts.always)
        }
        n.Animation = n.extend(lc, {
                tweener: function(a, b) {
                    n.isFunction(a) ? (b = a, a = ["*"]) : a = a.split(" ");
                    for (var c, d = 0, e = a.length; e > d; d++) c = a[d], fc[c] = fc[c] || [], fc[c].unshift(b)
                },
                prefilter: function(a, b) {
                    b ? ec.unshift(a) : ec.push(a)
                }
            }), n.speed = function(a, b, c) {
                var d = a && "object" == typeof a ? n.extend({}, a) : {
                    complete: c || !c && b || n.isFunction(a) && a,
                    duration: a,
                    easing: c && b || b && !n.isFunction(b) && b
                };
                return d.duration = n.fx.off ? 0 : "number" == typeof d.duration ? d.duration : d.duration in n.fx.speeds ? n.fx.speeds[d.duration] : n.fx.speeds._default, (null == d.queue || d.queue === !0) && (d.queue = "fx"), d.old = d.complete, d.complete = function() {
                    n.isFunction(d.old) && d.old.call(this), d.queue && n.dequeue(this, d.queue)
                }, d
            }, n.fn.extend({
                fadeTo: function(a, b, c, d) {
                    return this.filter(V).css("opacity", 0).show().end().animate({
                        opacity: b
                    }, a, c, d)
                },
                animate: function(a, b, c, d) {
                    var e = n.isEmptyObject(a),
                        f = n.speed(b, c, d),
                        g = function() {
                            var b = lc(this, n.extend({}, a), f);
                            (e || n._data(this, "finish")) && b.stop(!0)
                        };
                    return g.finish = g, e || f.queue === !1 ? this.each(g) : this.queue(f.queue, g)
                },
                stop: function(a, b, c) {
                    var d = function(a) {
                        var b = a.stop;
                        delete a.stop, b(c)
                    };
                    return "string" != typeof a && (c = b, b = a, a = void 0), b && a !== !1 && this.queue(a || "fx", []), this.each(function() {
                        var b = !0,
                            e = null != a && a + "queueHooks",
                            f = n.timers,
                            g = n._data(this);
                        if (e) g[e] && g[e].stop && d(g[e]);
                        else
                            for (e in g) g[e] && g[e].stop && dc.test(e) && d(g[e]);
                        for (e = f.length; e--;) f[e].elem !== this || null != a && f[e].queue !== a || (f[e].anim.stop(c), b = !1, f.splice(e, 1));
                        (b || !c) && n.dequeue(this, a)
                    })
                },
                finish: function(a) {
                    return a !== !1 && (a = a || "fx"), this.each(function() {
                        var b, c = n._data(this),
                            d = c[a + "queue"],
                            e = c[a + "queueHooks"],
                            f = n.timers,
                            g = d ? d.length : 0;
                        for (c.finish = !0, n.queue(this, a, []), e && e.stop && e.stop.call(this, !0), b = f.length; b--;) f[b].elem === this && f[b].queue === a && (f[b].anim.stop(!0), f.splice(b, 1));
                        for (b = 0; g > b; b++) d[b] && d[b].finish && d[b].finish.call(this);
                        delete c.finish
                    })
                }
            }), n.each(["toggle", "show", "hide"], function(a, b) {
                var c = n.fn[b];
                n.fn[b] = function(a, d, e) {
                    return null == a || "boolean" == typeof a ? c.apply(this, arguments) : this.animate(hc(b, !0), a, d, e)
                }
            }), n.each({
                slideDown: hc("show"),
                slideUp: hc("hide"),
                slideToggle: hc("toggle"),
                fadeIn: {
                    opacity: "show"
                },
                fadeOut: {
                    opacity: "hide"
                },
                fadeToggle: {
                    opacity: "toggle"
                }
            }, function(a, b) {
                n.fn[a] = function(a, c, d) {
                    return this.animate(b, a, c, d)
                }
            }), n.timers = [], n.fx.tick = function() {
                var a, b = n.timers,
                    c = 0;
                for (_b = n.now(); c < b.length; c++) a = b[c], a() || b[c] !== a || b.splice(c--, 1);
                b.length || n.fx.stop(), _b = void 0
            }, n.fx.timer = function(a) {
                n.timers.push(a), a() ? n.fx.start() : n.timers.pop()
            }, n.fx.interval = 13, n.fx.start = function() {
                ac || (ac = setInterval(n.fx.tick, n.fx.interval))
            }, n.fx.stop = function() {
                clearInterval(ac), ac = null
            }, n.fx.speeds = {
                slow: 600,
                fast: 200,
                _default: 400
            }, n.fn.delay = function(a, b) {
                return a = n.fx ? n.fx.speeds[a] || a : a, b = b || "fx", this.queue(b, function(b, c) {
                    var d = setTimeout(b, a);
                    c.stop = function() {
                        clearTimeout(d)
                    }
                })
            },
            function() {
                var a, b, c, d, e = z.createElement("div");
                e.setAttribute("className", "t"), e.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>", a = e.getElementsByTagName("a")[0], c = z.createElement("select"), d = c.appendChild(z.createElement("option")), b = e.getElementsByTagName("input")[0], a.style.cssText = "top:1px", l.getSetAttribute = "t" !== e.className, l.style = /top/.test(a.getAttribute("style")), l.hrefNormalized = "/a" === a.getAttribute("href"), l.checkOn = !!b.value, l.optSelected = d.selected, l.enctype = !!z.createElement("form").enctype, c.disabled = !0, l.optDisabled = !d.disabled, b = z.createElement("input"), b.setAttribute("value", ""), l.input = "" === b.getAttribute("value"), b.value = "t", b.setAttribute("type", "radio"), l.radioValue = "t" === b.value, a = b = c = d = e = null
            }();
        var mc = /\r/g;
        n.fn.extend({
            val: function(a) {
                var b, c, d, e = this[0]; {
                    if (arguments.length) return d = n.isFunction(a), this.each(function(c) {
                        var e;
                        1 === this.nodeType && (e = d ? a.call(this, c, n(this).val()) : a, null == e ? e = "" : "number" == typeof e ? e += "" : n.isArray(e) && (e = n.map(e, function(a) {
                            return null == a ? "" : a + ""
                        })), b = n.valHooks[this.type] || n.valHooks[this.nodeName.toLowerCase()], b && "set" in b && void 0 !== b.set(this, e, "value") || (this.value = e))
                    });
                    if (e) return b = n.valHooks[e.type] || n.valHooks[e.nodeName.toLowerCase()], b && "get" in b && void 0 !== (c = b.get(e, "value")) ? c : (c = e.value, "string" == typeof c ? c.replace(mc, "") : null == c ? "" : c)
                }
            }
        }), n.extend({
            valHooks: {
                option: {
                    get: function(a) {
                        var b = n.find.attr(a, "value");
                        return null != b ? b : n.text(a)
                    }
                },
                select: {
                    get: function(a) {
                        for (var b, c, d = a.options, e = a.selectedIndex, f = "select-one" === a.type || 0 > e, g = f ? null : [], h = f ? e + 1 : d.length, i = 0 > e ? h : f ? e : 0; h > i; i++)
                            if (c = d[i], !(!c.selected && i !== e || (l.optDisabled ? c.disabled : null !== c.getAttribute("disabled")) || c.parentNode.disabled && n.nodeName(c.parentNode, "optgroup"))) {
                                if (b = n(c).val(), f) return b;
                                g.push(b)
                            }
                        return g
                    },
                    set: function(a, b) {
                        var c, d, e = a.options,
                            f = n.makeArray(b),
                            g = e.length;
                        while (g--)
                            if (d = e[g], n.inArray(n.valHooks.option.get(d), f) >= 0) try {
                                d.selected = c = !0
                            } catch (h) {
                                d.scrollHeight
                            } else d.selected = !1;
                        return c || (a.selectedIndex = -1), e
                    }
                }
            }
        }), n.each(["radio", "checkbox"], function() {
            n.valHooks[this] = {
                set: function(a, b) {
                    return n.isArray(b) ? a.checked = n.inArray(n(a).val(), b) >= 0 : void 0
                }
            }, l.checkOn || (n.valHooks[this].get = function(a) {
                return null === a.getAttribute("value") ? "on" : a.value
            })
        });
        var nc, oc, pc = n.expr.attrHandle,
            qc = /^(?:checked|selected)$/i,
            rc = l.getSetAttribute,
            sc = l.input;
        n.fn.extend({
            attr: function(a, b) {
                return W(this, n.attr, a, b, arguments.length > 1)
            },
            removeAttr: function(a) {
                return this.each(function() {
                    n.removeAttr(this, a)
                })
            }
        }), n.extend({
            attr: function(a, b, c) {
                var d, e, f = a.nodeType;
                if (a && 3 !== f && 8 !== f && 2 !== f) return typeof a.getAttribute === L ? n.prop(a, b, c) : (1 === f && n.isXMLDoc(a) || (b = b.toLowerCase(), d = n.attrHooks[b] || (n.expr.match.bool.test(b) ? oc : nc)), void 0 === c ? d && "get" in d && null !== (e = d.get(a, b)) ? e : (e = n.find.attr(a, b), null == e ? void 0 : e) : null !== c ? d && "set" in d && void 0 !== (e = d.set(a, c, b)) ? e : (a.setAttribute(b, c + ""), c) : void n.removeAttr(a, b))
            },
            removeAttr: function(a, b) {
                var c, d, e = 0,
                    f = b && b.match(F);
                if (f && 1 === a.nodeType)
                    while (c = f[e++]) d = n.propFix[c] || c, n.expr.match.bool.test(c) ? sc && rc || !qc.test(c) ? a[d] = !1 : a[n.camelCase("default-" + c)] = a[d] = !1 : n.attr(a, c, ""), a.removeAttribute(rc ? c : d)
            },
            attrHooks: {
                type: {
                    set: function(a, b) {
                        if (!l.radioValue && "radio" === b && n.nodeName(a, "input")) {
                            var c = a.value;
                            return a.setAttribute("type", b), c && (a.value = c), b
                        }
                    }
                }
            }
        }), oc = {
            set: function(a, b, c) {
                return b === !1 ? n.removeAttr(a, c) : sc && rc || !qc.test(c) ? a.setAttribute(!rc && n.propFix[c] || c, c) : a[n.camelCase("default-" + c)] = a[c] = !0, c
            }
        }, n.each(n.expr.match.bool.source.match(/\w+/g), function(a, b) {
            var c = pc[b] || n.find.attr;
            pc[b] = sc && rc || !qc.test(b) ? function(a, b, d) {
                var e, f;
                return d || (f = pc[b], pc[b] = e, e = null != c(a, b, d) ? b.toLowerCase() : null, pc[b] = f), e
            } : function(a, b, c) {
                return c ? void 0 : a[n.camelCase("default-" + b)] ? b.toLowerCase() : null
            }
        }), sc && rc || (n.attrHooks.value = {
            set: function(a, b, c) {
                return n.nodeName(a, "input") ? void(a.defaultValue = b) : nc && nc.set(a, b, c)
            }
        }), rc || (nc = {
            set: function(a, b, c) {
                var d = a.getAttributeNode(c);
                return d || a.setAttributeNode(d = a.ownerDocument.createAttribute(c)), d.value = b += "", "value" === c || b === a.getAttribute(c) ? b : void 0
            }
        }, pc.id = pc.name = pc.coords = function(a, b, c) {
            var d;
            return c ? void 0 : (d = a.getAttributeNode(b)) && "" !== d.value ? d.value : null
        }, n.valHooks.button = {
            get: function(a, b) {
                var c = a.getAttributeNode(b);
                return c && c.specified ? c.value : void 0
            },
            set: nc.set
        }, n.attrHooks.contenteditable = {
            set: function(a, b, c) {
                nc.set(a, "" === b ? !1 : b, c)
            }
        }, n.each(["width", "height"], function(a, b) {
            n.attrHooks[b] = {
                set: function(a, c) {
                    return "" === c ? (a.setAttribute(b, "auto"), c) : void 0
                }
            }
        })), l.style || (n.attrHooks.style = {
            get: function(a) {
                return a.style.cssText || void 0
            },
            set: function(a, b) {
                return a.style.cssText = b + ""
            }
        });
        var tc = /^(?:input|select|textarea|button|object)$/i,
            uc = /^(?:a|area)$/i;
        n.fn.extend({
            prop: function(a, b) {
                return W(this, n.prop, a, b, arguments.length > 1)
            },
            removeProp: function(a) {
                return a = n.propFix[a] || a, this.each(function() {
                    try {
                        this[a] = void 0, delete this[a]
                    } catch (b) {}
                })
            }
        }), n.extend({
            propFix: {
                "for": "htmlFor",
                "class": "className"
            },
            prop: function(a, b, c) {
                var d, e, f, g = a.nodeType;
                if (a && 3 !== g && 8 !== g && 2 !== g) return f = 1 !== g || !n.isXMLDoc(a), f && (b = n.propFix[b] || b, e = n.propHooks[b]), void 0 !== c ? e && "set" in e && void 0 !== (d = e.set(a, c, b)) ? d : a[b] = c : e && "get" in e && null !== (d = e.get(a, b)) ? d : a[b]
            },
            propHooks: {
                tabIndex: {
                    get: function(a) {
                        var b = n.find.attr(a, "tabindex");
                        return b ? parseInt(b, 10) : tc.test(a.nodeName) || uc.test(a.nodeName) && a.href ? 0 : -1
                    }
                }
            }
        }), l.hrefNormalized || n.each(["href", "src"], function(a, b) {
            n.propHooks[b] = {
                get: function(a) {
                    return a.getAttribute(b, 4)
                }
            }
        }), l.optSelected || (n.propHooks.selected = {
            get: function(a) {
                var b = a.parentNode;
                return b && (b.selectedIndex, b.parentNode && b.parentNode.selectedIndex), null
            }
        }), n.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function() {
            n.propFix[this.toLowerCase()] = this
        }), l.enctype || (n.propFix.enctype = "encoding");
        var vc = /[\t\r\n\f]/g;
        n.fn.extend({
            addClass: function(a) {
                var b, c, d, e, f, g, h = 0,
                    i = this.length,
                    j = "string" == typeof a && a;
                if (n.isFunction(a)) return this.each(function(b) {
                    n(this).addClass(a.call(this, b, this.className))
                });
                if (j)
                    for (b = (a || "").match(F) || []; i > h; h++)
                        if (c = this[h], d = 1 === c.nodeType && (c.className ? (" " + c.className + " ").replace(vc, " ") : " ")) {
                            f = 0;
                            while (e = b[f++]) d.indexOf(" " + e + " ") < 0 && (d += e + " ");
                            g = n.trim(d), c.className !== g && (c.className = g)
                        }
                return this
            },
            removeClass: function(a) {
                var b, c, d, e, f, g, h = 0,
                    i = this.length,
                    j = 0 === arguments.length || "string" == typeof a && a;
                if (n.isFunction(a)) return this.each(function(b) {
                    n(this).removeClass(a.call(this, b, this.className))
                });
                if (j)
                    for (b = (a || "").match(F) || []; i > h; h++)
                        if (c = this[h], d = 1 === c.nodeType && (c.className ? (" " + c.className + " ").replace(vc, " ") : "")) {
                            f = 0;
                            while (e = b[f++])
                                while (d.indexOf(" " + e + " ") >= 0) d = d.replace(" " + e + " ", " ");
                            g = a ? n.trim(d) : "", c.className !== g && (c.className = g)
                        }
                return this
            },
            toggleClass: function(a, b) {
                var c = typeof a;
                return "boolean" == typeof b && "string" === c ? b ? this.addClass(a) : this.removeClass(a) : this.each(n.isFunction(a) ? function(c) {
                    n(this).toggleClass(a.call(this, c, this.className, b), b)
                } : function() {
                    if ("string" === c) {
                        var b, d = 0,
                            e = n(this),
                            f = a.match(F) || [];
                        while (b = f[d++]) e.hasClass(b) ? e.removeClass(b) : e.addClass(b)
                    } else(c === L || "boolean" === c) && (this.className && n._data(this, "__className__", this.className), this.className = this.className || a === !1 ? "" : n._data(this, "__className__") || "")
                })
            },
            hasClass: function(a) {
                for (var b = " " + a + " ", c = 0, d = this.length; d > c; c++)
                    if (1 === this[c].nodeType && (" " + this[c].className + " ").replace(vc, " ").indexOf(b) >= 0) return !0;
                return !1
            }
        }), n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "), function(a, b) {
            n.fn[b] = function(a, c) {
                return arguments.length > 0 ? this.on(b, null, a, c) : this.trigger(b)
            }
        }), n.fn.extend({
            hover: function(a, b) {
                return this.mouseenter(a).mouseleave(b || a)
            },
            bind: function(a, b, c) {
                return this.on(a, null, b, c)
            },
            unbind: function(a, b) {
                return this.off(a, null, b)
            },
            delegate: function(a, b, c, d) {
                return this.on(b, a, c, d)
            },
            undelegate: function(a, b, c) {
                return 1 === arguments.length ? this.off(a, "**") : this.off(b, a || "**", c)
            }
        });
        var wc = n.now(),
            xc = /\?/,
            yc = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
        n.parseJSON = function(b) {
            if (a.JSON && a.JSON.parse) return a.JSON.parse(b + "");
            var c, d = null,
                e = n.trim(b + "");
            return e && !n.trim(e.replace(yc, function(a, b, e, f) {
                return c && b && (d = 0), 0 === d ? a : (c = e || b, d += !f - !e, "")
            })) ? Function("return " + e)() : n.error("Invalid JSON: " + b)
        }, n.parseXML = function(b) {
            var c, d;
            if (!b || "string" != typeof b) return null;
            try {
                a.DOMParser ? (d = new DOMParser, c = d.parseFromString(b, "text/xml")) : (c = new ActiveXObject("Microsoft.XMLDOM"), c.async = "false", c.loadXML(b))
            } catch (e) {
                c = void 0
            }
            return c && c.documentElement && !c.getElementsByTagName("parsererror").length || n.error("Invalid XML: " + b), c
        };
        var zc, Ac, Bc = /#.*$/,
            Cc = /([?&])_=[^&]*/,
            Dc = /^(.*?):[ \t]*([^\r\n]*)\r?$/gm,
            Ec = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
            Fc = /^(?:GET|HEAD)$/,
            Gc = /^\/\//,
            Hc = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
            Ic = {},
            Jc = {},
            Kc = "*/".concat("*");
        try {
            Ac = location.href
        } catch (Lc) {
            Ac = z.createElement("a"), Ac.href = "", Ac = Ac.href
        }
        zc = Hc.exec(Ac.toLowerCase()) || [];
    
        function Mc(a) {
            return function(b, c) {
                "string" != typeof b && (c = b, b = "*");
                var d, e = 0,
                    f = b.toLowerCase().match(F) || [];
                if (n.isFunction(c))
                    while (d = f[e++]) "+" === d.charAt(0) ? (d = d.slice(1) || "*", (a[d] = a[d] || []).unshift(c)) : (a[d] = a[d] || []).push(c)
            }
        }
    
        function Nc(a, b, c, d) {
            var e = {},
                f = a === Jc;
    
            function g(h) {
                var i;
                return e[h] = !0, n.each(a[h] || [], function(a, h) {
                    var j = h(b, c, d);
                    return "string" != typeof j || f || e[j] ? f ? !(i = j) : void 0 : (b.dataTypes.unshift(j), g(j), !1)
                }), i
            }
            return g(b.dataTypes[0]) || !e["*"] && g("*")
        }
    
        function Oc(a, b) {
            var c, d, e = n.ajaxSettings.flatOptions || {};
            for (d in b) void 0 !== b[d] && ((e[d] ? a : c || (c = {}))[d] = b[d]);
            return c && n.extend(!0, a, c), a
        }
    
        function Pc(a, b, c) {
            var d, e, f, g, h = a.contents,
                i = a.dataTypes;
            while ("*" === i[0]) i.shift(), void 0 === e && (e = a.mimeType || b.getResponseHeader("Content-Type"));
            if (e)
                for (g in h)
                    if (h[g] && h[g].test(e)) {
                        i.unshift(g);
                        break
                    }
            if (i[0] in c) f = i[0];
            else {
                for (g in c) {
                    if (!i[0] || a.converters[g + " " + i[0]]) {
                        f = g;
                        break
                    }
                    d || (d = g)
                }
                f = f || d
            }
            return f ? (f !== i[0] && i.unshift(f), c[f]) : void 0
        }
    
        function Qc(a, b, c, d) {
            var e, f, g, h, i, j = {},
                k = a.dataTypes.slice();
            if (k[1])
                for (g in a.converters) j[g.toLowerCase()] = a.converters[g];
            f = k.shift();
            while (f)
                if (a.responseFields[f] && (c[a.responseFields[f]] = b), !i && d && a.dataFilter && (b = a.dataFilter(b, a.dataType)), i = f, f = k.shift())
                    if ("*" === f) f = i;
                    else if ("*" !== i && i !== f) {
                if (g = j[i + " " + f] || j["* " + f], !g)
                    for (e in j)
                        if (h = e.split(" "), h[1] === f && (g = j[i + " " + h[0]] || j["* " + h[0]])) {
                            g === !0 ? g = j[e] : j[e] !== !0 && (f = h[0], k.unshift(h[1]));
                            break
                        }
                if (g !== !0)
                    if (g && a["throws"]) b = g(b);
                    else try {
                        b = g(b)
                    } catch (l) {
                        return {
                            state: "parsererror",
                            error: g ? l : "No conversion from " + i + " to " + f
                        }
                    }
            }
            return {
                state: "success",
                data: b
            }
        }
        n.extend({
            active: 0,
            lastModified: {},
            etag: {},
            ajaxSettings: {
                url: Ac,
                type: "GET",
                isLocal: Ec.test(zc[1]),
                global: !0,
                processData: !0,
                async: !0,
                contentType: "application/x-www-form-urlencoded; charset=UTF-8",
                accepts: {
                    "*": Kc,
                    text: "text/plain",
                    html: "text/html",
                    xml: "application/xml, text/xml",
                    json: "application/json, text/javascript"
                },
                contents: {
                    xml: /xml/,
                    html: /html/,
                    json: /json/
                },
                responseFields: {
                    xml: "responseXML",
                    text: "responseText",
                    json: "responseJSON"
                },
                converters: {
                    "* text": String,
                    "text html": !0,
                    "text json": n.parseJSON,
                    "text xml": n.parseXML
                },
                flatOptions: {
                    url: !0,
                    context: !0
                }
            },
            ajaxSetup: function(a, b) {
                return b ? Oc(Oc(a, n.ajaxSettings), b) : Oc(n.ajaxSettings, a)
            },
            ajaxPrefilter: Mc(Ic),
            ajaxTransport: Mc(Jc),
            ajax: function(a, b) {
                "object" == typeof a && (b = a, a = void 0), b = b || {};
                var c, d, e, f, g, h, i, j, k = n.ajaxSetup({}, b),
                    l = k.context || k,
                    m = k.context && (l.nodeType || l.jquery) ? n(l) : n.event,
                    o = n.Deferred(),
                    p = n.Callbacks("once memory"),
                    q = k.statusCode || {},
                    r = {},
                    s = {},
                    t = 0,
                    u = "canceled",
                    v = {
                        readyState: 0,
                        getResponseHeader: function(a) {
                            var b;
                            if (2 === t) {
                                if (!j) {
                                    j = {};
                                    while (b = Dc.exec(f)) j[b[1].toLowerCase()] = b[2]
                                }
                                b = j[a.toLowerCase()]
                            }
                            return null == b ? null : b
                        },
                        getAllResponseHeaders: function() {
                            return 2 === t ? f : null
                        },
                        setRequestHeader: function(a, b) {
                            var c = a.toLowerCase();
                            return t || (a = s[c] = s[c] || a, r[a] = b), this
                        },
                        overrideMimeType: function(a) {
                            return t || (k.mimeType = a), this
                        },
                        statusCode: function(a) {
                            var b;
                            if (a)
                                if (2 > t)
                                    for (b in a) q[b] = [q[b], a[b]];
                                else v.always(a[v.status]);
                            return this
                        },
                        abort: function(a) {
                            var b = a || u;
                            return i && i.abort(b), x(0, b), this
                        }
                    };
                if (o.promise(v).complete = p.add, v.success = v.done, v.error = v.fail, k.url = ((a || k.url || Ac) + "").replace(Bc, "").replace(Gc, zc[1] + "//"), k.type = b.method || b.type || k.method || k.type, k.dataTypes = n.trim(k.dataType || "*").toLowerCase().match(F) || [""], null == k.crossDomain && (c = Hc.exec(k.url.toLowerCase()), k.crossDomain = !(!c || c[1] === zc[1] && c[2] === zc[2] && (c[3] || ("http:" === c[1] ? "80" : "443")) === (zc[3] || ("http:" === zc[1] ? "80" : "443")))), k.data && k.processData && "string" != typeof k.data && (k.data = n.param(k.data, k.traditional)), Nc(Ic, k, b, v), 2 === t) return v;
                h = k.global, h && 0 === n.active++ && n.event.trigger("ajaxStart"), k.type = k.type.toUpperCase(), k.hasContent = !Fc.test(k.type), e = k.url, k.hasContent || (k.data && (e = k.url += (xc.test(e) ? "&" : "?") + k.data, delete k.data), k.cache === !1 && (k.url = Cc.test(e) ? e.replace(Cc, "$1_=" + wc++) : e + (xc.test(e) ? "&" : "?") + "_=" + wc++)), k.ifModified && (n.lastModified[e] && v.setRequestHeader("If-Modified-Since", n.lastModified[e]), n.etag[e] && v.setRequestHeader("If-None-Match", n.etag[e])), (k.data && k.hasContent && k.contentType !== !1 || b.contentType) && v.setRequestHeader("Content-Type", k.contentType), v.setRequestHeader("Accept", k.dataTypes[0] && k.accepts[k.dataTypes[0]] ? k.accepts[k.dataTypes[0]] + ("*" !== k.dataTypes[0] ? ", " + Kc + "; q=0.01" : "") : k.accepts["*"]);
                for (d in k.headers) v.setRequestHeader(d, k.headers[d]);
                if (k.beforeSend && (k.beforeSend.call(l, v, k) === !1 || 2 === t)) return v.abort();
                u = "abort";
                for (d in {
                        success: 1,
                        error: 1,
                        complete: 1
                    }) v[d](k[d]);
                if (i = Nc(Jc, k, b, v)) {
                    v.readyState = 1, h && m.trigger("ajaxSend", [v, k]), k.async && k.timeout > 0 && (g = setTimeout(function() {
                        v.abort("timeout")
                    }, k.timeout));
                    try {
                        t = 1, i.send(r, x)
                    } catch (w) {
                        if (!(2 > t)) throw w;
                        x(-1, w)
                    }
                } else x(-1, "No Transport");
    
                function x(a, b, c, d) {
                    var j, r, s, u, w, x = b;
                    2 !== t && (t = 2, g && clearTimeout(g), i = void 0, f = d || "", v.readyState = a > 0 ? 4 : 0, j = a >= 200 && 300 > a || 304 === a, c && (u = Pc(k, v, c)), u = Qc(k, u, v, j), j ? (k.ifModified && (w = v.getResponseHeader("Last-Modified"), w && (n.lastModified[e] = w), w = v.getResponseHeader("etag"), w && (n.etag[e] = w)), 204 === a || "HEAD" === k.type ? x = "nocontent" : 304 === a ? x = "notmodified" : (x = u.state, r = u.data, s = u.error, j = !s)) : (s = x, (a || !x) && (x = "error", 0 > a && (a = 0))), v.status = a, v.statusText = (b || x) + "", j ? o.resolveWith(l, [r, x, v]) : o.rejectWith(l, [v, x, s]), v.statusCode(q), q = void 0, h && m.trigger(j ? "ajaxSuccess" : "ajaxError", [v, k, j ? r : s]), p.fireWith(l, [v, x]), h && (m.trigger("ajaxComplete", [v, k]), --n.active || n.event.trigger("ajaxStop")))
                }
                return v
            },
            getJSON: function(a, b, c) {
                return n.get(a, b, c, "json")
            },
            getScript: function(a, b) {
                return n.get(a, void 0, b, "script")
            }
        }), n.each(["get", "post"], function(a, b) {
            n[b] = function(a, c, d, e) {
                return n.isFunction(c) && (e = e || d, d = c, c = void 0), n.ajax({
                    url: a,
                    type: b,
                    dataType: e,
                    data: c,
                    success: d
                })
            }
        }), n.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function(a, b) {
            n.fn[b] = function(a) {
                return this.on(b, a)
            }
        }), n._evalUrl = function(a) {
            return n.ajax({
                url: a,
                type: "GET",
                dataType: "script",
                async: !1,
                global: !1,
                "throws": !0
            })
        }, n.fn.extend({
            wrapAll: function(a) {
                if (n.isFunction(a)) return this.each(function(b) {
                    n(this).wrapAll(a.call(this, b))
                });
                if (this[0]) {
                    var b = n(a, this[0].ownerDocument).eq(0).clone(!0);
                    this[0].parentNode && b.insertBefore(this[0]), b.map(function() {
                        var a = this;
                        while (a.firstChild && 1 === a.firstChild.nodeType) a = a.firstChild;
                        return a
                    }).append(this)
                }
                return this
            },
            wrapInner: function(a) {
                return this.each(n.isFunction(a) ? function(b) {
                    n(this).wrapInner(a.call(this, b))
                } : function() {
                    var b = n(this),
                        c = b.contents();
                    c.length ? c.wrapAll(a) : b.append(a)
                })
            },
            wrap: function(a) {
                var b = n.isFunction(a);
                return this.each(function(c) {
                    n(this).wrapAll(b ? a.call(this, c) : a)
                })
            },
            unwrap: function() {
                return this.parent().each(function() {
                    n.nodeName(this, "body") || n(this).replaceWith(this.childNodes)
                }).end()
            }
        }), n.expr.filters.hidden = function(a) {
            return a.offsetWidth <= 0 && a.offsetHeight <= 0 || !l.reliableHiddenOffsets() && "none" === (a.style && a.style.display || n.css(a, "display"))
        }, n.expr.filters.visible = function(a) {
            return !n.expr.filters.hidden(a)
        };
        var Rc = /%20/g,
            Sc = /\[\]$/,
            Tc = /\r?\n/g,
            Uc = /^(?:submit|button|image|reset|file)$/i,
            Vc = /^(?:input|select|textarea|keygen)/i;
    
        function Wc(a, b, c, d) {
            var e;
            if (n.isArray(b)) n.each(b, function(b, e) {
                c || Sc.test(a) ? d(a, e) : Wc(a + "[" + ("object" == typeof e ? b : "") + "]", e, c, d)
            });
            else if (c || "object" !== n.type(b)) d(a, b);
            else
                for (e in b) Wc(a + "[" + e + "]", b[e], c, d)
        }
        n.param = function(a, b) {
            var c, d = [],
                e = function(a, b) {
                    b = n.isFunction(b) ? b() : null == b ? "" : b, d[d.length] = encodeURIComponent(a) + "=" + encodeURIComponent(b)
                };
            if (void 0 === b && (b = n.ajaxSettings && n.ajaxSettings.traditional), n.isArray(a) || a.jquery && !n.isPlainObject(a)) n.each(a, function() {
                e(this.name, this.value)
            });
            else
                for (c in a) Wc(c, a[c], b, e);
            return d.join("&").replace(Rc, "+")
        }, n.fn.extend({
            serialize: function() {
                return n.param(this.serializeArray())
            },
            serializeArray: function() {
                return this.map(function() {
                    var a = n.prop(this, "elements");
                    return a ? n.makeArray(a) : this
                }).filter(function() {
                    var a = this.type;
                    return this.name && !n(this).is(":disabled") && Vc.test(this.nodeName) && !Uc.test(a) && (this.checked || !X.test(a))
                }).map(function(a, b) {
                    var c = n(this).val();
                    return null == c ? null : n.isArray(c) ? n.map(c, function(a) {
                        return {
                            name: b.name,
                            value: a.replace(Tc, "\r\n")
                        }
                    }) : {
                        name: b.name,
                        value: c.replace(Tc, "\r\n")
                    }
                }).get()
            }
        }), n.ajaxSettings.xhr = void 0 !== a.ActiveXObject ? function() {
            return !this.isLocal && /^(get|post|head|put|delete|options)$/i.test(this.type) && $c() || _c()
        } : $c;
        var Xc = 0,
            Yc = {},
            Zc = n.ajaxSettings.xhr();
        a.ActiveXObject && n(a).on("unload", function() {
            for (var a in Yc) Yc[a](void 0, !0)
        }), l.cors = !!Zc && "withCredentials" in Zc, Zc = l.ajax = !!Zc, Zc && n.ajaxTransport(function(a) {
            if (!a.crossDomain || l.cors) {
                var b;
                return {
                    send: function(c, d) {
                        var e, f = a.xhr(),
                            g = ++Xc;
                        if (f.open(a.type, a.url, a.async, a.username, a.password), a.xhrFields)
                            for (e in a.xhrFields) f[e] = a.xhrFields[e];
                        a.mimeType && f.overrideMimeType && f.overrideMimeType(a.mimeType), a.crossDomain || c["X-Requested-With"] || (c["X-Requested-With"] = "XMLHttpRequest");
                        for (e in c) void 0 !== c[e] && f.setRequestHeader(e, c[e] + "");
                        f.send(a.hasContent && a.data || null), b = function(c, e) {
                            var h, i, j;
                            if (b && (e || 4 === f.readyState))
                                if (delete Yc[g], b = void 0, f.onreadystatechange = n.noop, e) 4 !== f.readyState && f.abort();
                                else {
                                    j = {}, h = f.status, "string" == typeof f.responseText && (j.text = f.responseText);
                                    try {
                                        i = f.statusText
                                    } catch (k) {
                                        i = ""
                                    }
                                    h || !a.isLocal || a.crossDomain ? 1223 === h && (h = 204) : h = j.text ? 200 : 404
                                }
                            j && d(h, i, j, f.getAllResponseHeaders())
                        }, a.async ? 4 === f.readyState ? setTimeout(b) : f.onreadystatechange = Yc[g] = b : b()
                    },
                    abort: function() {
                        b && b(void 0, !0)
                    }
                }
            }
        });
    
        function $c() {
            try {
                return new a.XMLHttpRequest
            } catch (b) {}
        }
    
        function _c() {
            try {
                return new a.ActiveXObject("Microsoft.XMLHTTP")
            } catch (b) {}
        }
        n.ajaxSetup({
            accepts: {
                script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
            },
            contents: {
                script: /(?:java|ecma)script/
            },
            converters: {
                "text script": function(a) {
                    return n.globalEval(a), a
                }
            }
        }), n.ajaxPrefilter("script", function(a) {
            void 0 === a.cache && (a.cache = !1), a.crossDomain && (a.type = "GET", a.global = !1)
        }), n.ajaxTransport("script", function(a) {
            if (a.crossDomain) {
                var b, c = z.head || n("head")[0] || z.documentElement;
                return {
                    send: function(d, e) {
                        b = z.createElement("script"), b.async = !0, a.scriptCharset && (b.charset = a.scriptCharset), b.src = a.url, b.onload = b.onreadystatechange = function(a, c) {
                            (c || !b.readyState || /loaded|complete/.test(b.readyState)) && (b.onload = b.onreadystatechange = null, b.parentNode && b.parentNode.removeChild(b), b = null, c || e(200, "success"))
                        }, c.insertBefore(b, c.firstChild)
                    },
                    abort: function() {
                        b && b.onload(void 0, !0)
                    }
                }
            }
        });
        var ad = [],
            bd = /(=)\?(?=&|$)|\?\?/;
        n.ajaxSetup({
            jsonp: "callback",
            jsonpCallback: function() {
                var a = ad.pop() || n.expando + "_" + wc++;
                return this[a] = !0, a
            }
        }), n.ajaxPrefilter("json jsonp", function(b, c, d) {
            var e, f, g, h = b.jsonp !== !1 && (bd.test(b.url) ? "url" : "string" == typeof b.data && !(b.contentType || "").indexOf("application/x-www-form-urlencoded") && bd.test(b.data) && "data");
            return h || "jsonp" === b.dataTypes[0] ? (e = b.jsonpCallback = n.isFunction(b.jsonpCallback) ? b.jsonpCallback() : b.jsonpCallback, h ? b[h] = b[h].replace(bd, "$1" + e) : b.jsonp !== !1 && (b.url += (xc.test(b.url) ? "&" : "?") + b.jsonp + "=" + e), b.converters["script json"] = function() {
                return g || n.error(e + " was not called"), g[0]
            }, b.dataTypes[0] = "json", f = a[e], a[e] = function() {
                g = arguments
            }, d.always(function() {
                a[e] = f, b[e] && (b.jsonpCallback = c.jsonpCallback, ad.push(e)), g && n.isFunction(f) && f(g[0]), g = f = void 0
            }), "script") : void 0
        }), n.parseHTML = function(a, b, c) {
            if (!a || "string" != typeof a) return null;
            "boolean" == typeof b && (c = b, b = !1), b = b || z;
            var d = v.exec(a),
                e = !c && [];
            return d ? [b.createElement(d[1])] : (d = n.buildFragment([a], b, e), e && e.length && n(e).remove(), n.merge([], d.childNodes))
        };
        var cd = n.fn.load;
        n.fn.load = function(a, b, c) {
            if ("string" != typeof a && cd) return cd.apply(this, arguments);
            var d, e, f, g = this,
                h = a.indexOf(" ");
            return h >= 0 && (d = a.slice(h, a.length), a = a.slice(0, h)), n.isFunction(b) ? (c = b, b = void 0) : b && "object" == typeof b && (f = "POST"), g.length > 0 && n.ajax({
                url: a,
                type: f,
                dataType: "html",
                data: b
            }).done(function(a) {
                e = arguments, g.html(d ? n("<div>").append(n.parseHTML(a)).find(d) : a)
            }).complete(c && function(a, b) {
                g.each(c, e || [a.responseText, b, a])
            }), this
        }, n.expr.filters.animated = function(a) {
            return n.grep(n.timers, function(b) {
                return a === b.elem
            }).length
        };
        var dd = a.document.documentElement;
    
        function ed(a) {
            return n.isWindow(a) ? a : 9 === a.nodeType ? a.defaultView || a.parentWindow : !1
        }
        n.offset = {
            setOffset: function(a, b, c) {
                var d, e, f, g, h, i, j, k = n.css(a, "position"),
                    l = n(a),
                    m = {};
                "static" === k && (a.style.position = "relative"), h = l.offset(), f = n.css(a, "top"), i = n.css(a, "left"), j = ("absolute" === k || "fixed" === k) && n.inArray("auto", [f, i]) > -1, j ? (d = l.position(), g = d.top, e = d.left) : (g = parseFloat(f) || 0, e = parseFloat(i) || 0), n.isFunction(b) && (b = b.call(a, c, h)), null != b.top && (m.top = b.top - h.top + g), null != b.left && (m.left = b.left - h.left + e), "using" in b ? b.using.call(a, m) : l.css(m)
            }
        }, n.fn.extend({
            offset: function(a) {
                if (arguments.length) return void 0 === a ? this : this.each(function(b) {
                    n.offset.setOffset(this, a, b)
                });
                var b, c, d = {
                        top: 0,
                        left: 0
                    },
                    e = this[0],
                    f = e && e.ownerDocument;
                if (f) return b = f.documentElement, n.contains(b, e) ? (typeof e.getBoundingClientRect !== L && (d = e.getBoundingClientRect()), c = ed(f), {
                    top: d.top + (c.pageYOffset || b.scrollTop) - (b.clientTop || 0),
                    left: d.left + (c.pageXOffset || b.scrollLeft) - (b.clientLeft || 0)
                }) : d
            },
            position: function() {
                if (this[0]) {
                    var a, b, c = {
                            top: 0,
                            left: 0
                        },
                        d = this[0];
                    return "fixed" === n.css(d, "position") ? b = d.getBoundingClientRect() : (a = this.offsetParent(), b = this.offset(), n.nodeName(a[0], "html") || (c = a.offset()), c.top += n.css(a[0], "borderTopWidth", !0), c.left += n.css(a[0], "borderLeftWidth", !0)), {
                        top: b.top - c.top - n.css(d, "marginTop", !0),
                        left: b.left - c.left - n.css(d, "marginLeft", !0)
                    }
                }
            },
            offsetParent: function() {
                return this.map(function() {
                    var a = this.offsetParent || dd;
                    while (a && !n.nodeName(a, "html") && "static" === n.css(a, "position")) a = a.offsetParent;
                    return a || dd
                })
            }
        }), n.each({
            scrollLeft: "pageXOffset",
            scrollTop: "pageYOffset"
        }, function(a, b) {
            var c = /Y/.test(b);
            n.fn[a] = function(d) {
                return W(this, function(a, d, e) {
                    var f = ed(a);
                    return void 0 === e ? f ? b in f ? f[b] : f.document.documentElement[d] : a[d] : void(f ? f.scrollTo(c ? n(f).scrollLeft() : e, c ? e : n(f).scrollTop()) : a[d] = e)
                }, a, d, arguments.length, null)
            }
        }), n.each(["top", "left"], function(a, b) {
            n.cssHooks[b] = Mb(l.pixelPosition, function(a, c) {
                return c ? (c = Kb(a, b), Ib.test(c) ? n(a).position()[b] + "px" : c) : void 0
            })
        }), n.each({
            Height: "height",
            Width: "width"
        }, function(a, b) {
            n.each({
                padding: "inner" + a,
                content: b,
                "": "outer" + a
            }, function(c, d) {
                n.fn[d] = function(d, e) {
                    var f = arguments.length && (c || "boolean" != typeof d),
                        g = c || (d === !0 || e === !0 ? "margin" : "border");
                    return W(this, function(b, c, d) {
                        var e;
                        return n.isWindow(b) ? b.document.documentElement["client" + a] : 9 === b.nodeType ? (e = b.documentElement, Math.max(b.body["scroll" + a], e["scroll" + a], b.body["offset" + a], e["offset" + a], e["client" + a])) : void 0 === d ? n.css(b, c, g) : n.style(b, c, d, g)
                    }, b, f ? d : void 0, f, null)
                }
            })
        }), n.fn.size = function() {
            return this.length
        }, n.fn.andSelf = n.fn.addBack, "function" == typeof define && define.amd && define("jquery", [], function() {
            return n
        });
        var fd = a.jQuery,
            gd = a.$;
        return n.noConflict = function(b) {
            return a.$ === n && (a.$ = gd), b && a.jQuery === n && (a.jQuery = fd), n
        }, typeof b === L && (a.jQuery = a.$ = n), n
    });
    /*! RESOURCE: /scripts/thirdparty/cometd/jquery/jquery-1.11.0_no_conflict.js */
    (function() {
        window.jQuery1110 = jQuery.noConflict(true);
    })();;
    /*! RESOURCE: /scripts/thirdparty/cometd/org/cometd.js */
    this.org = this.org || {};
    org.cometd = {};
    org.cometd.JSON = {};
    org.cometd.JSON.toJSON = org.cometd.JSON.fromJSON = function(object) {
        throw 'Abstract';
    };
    org.cometd.Utils = {};
    org.cometd.Utils.isString = function(value) {
        if (value === undefined || value === null) {
            return false;
        }
        return typeof value === 'string' || value instanceof String;
    };
    org.cometd.Utils.isArray = function(value) {
        if (value === undefined || value === null) {
            return false;
        }
        return value instanceof Array;
    };
    org.cometd.Utils.inArray = function(element, array) {
        for (var i = 0; i < array.length; ++i) {
            if (element === array[i]) {
                return i;
            }
        }
        return -1;
    };
    org.cometd.Utils.setTimeout = function(cometd, funktion, delay) {
        return window.setTimeout(function() {
            try {
                funktion();
            } catch (x) {
                cometd._debug('Exception invoking timed function', funktion, x);
            }
        }, delay);
    };
    org.cometd.Utils.clearTimeout = function(timeoutHandle) {
        window.clearTimeout(timeoutHandle);
    };
    org.cometd.TransportRegistry = function() {
        var _types = [];
        var _transports = {};
        this.getTransportTypes = function() {
            return _types.slice(0);
        };
        this.findTransportTypes = function(version, crossDomain, url) {
            var result = [];
            for (var i = 0; i < _types.length; ++i) {
                var type = _types[i];
                if (_transports[type].accept(version, crossDomain, url) === true) {
                    result.push(type);
                }
            }
            return result;
        };
        this.negotiateTransport = function(types, version, crossDomain, url) {
            for (var i = 0; i < _types.length; ++i) {
                var type = _types[i];
                for (var j = 0; j < types.length; ++j) {
                    if (type === types[j]) {
                        var transport = _transports[type];
                        if (transport.accept(version, crossDomain, url) === true) {
                            return transport;
                        }
                    }
                }
            }
            return null;
        };
        this.add = function(type, transport, index) {
            var existing = false;
            for (var i = 0; i < _types.length; ++i) {
                if (_types[i] === type) {
                    existing = true;
                    break;
                }
            }
            if (!existing) {
                if (typeof index !== 'number') {
                    _types.push(type);
                } else {
                    _types.splice(index, 0, type);
                }
                _transports[type] = transport;
            }
            return !existing;
        };
        this.find = function(type) {
            for (var i = 0; i < _types.length; ++i) {
                if (_types[i] === type) {
                    return _transports[type];
                }
            }
            return null;
        };
        this.remove = function(type) {
            for (var i = 0; i < _types.length; ++i) {
                if (_types[i] === type) {
                    _types.splice(i, 1);
                    var transport = _transports[type];
                    delete _transports[type];
                    return transport;
                }
            }
            return null;
        };
        this.clear = function() {
            _types = [];
            _transports = {};
        };
        this.reset = function() {
            for (var i = 0; i < _types.length; ++i) {
                _transports[_types[i]].reset();
            }
        };
    };
    org.cometd.Transport = function() {
        var _type;
        var _cometd;
        this.registered = function(type, cometd) {
            _type = type;
            _cometd = cometd;
        };
        this.unregistered = function() {
            _type = null;
            _cometd = null;
        };
        this._debug = function() {
            _cometd._debug.apply(_cometd, arguments);
        };
        this._mixin = function() {
            return _cometd._mixin.apply(_cometd, arguments);
        };
        this.getConfiguration = function() {
            return _cometd.getConfiguration();
        };
        this.getAdvice = function() {
            return _cometd.getAdvice();
        };
        this.setTimeout = function(funktion, delay) {
            return org.cometd.Utils.setTimeout(_cometd, funktion, delay);
        };
        this.clearTimeout = function(handle) {
            org.cometd.Utils.clearTimeout(handle);
        };
        this.convertToMessages = function(response) {
            if (org.cometd.Utils.isString(response)) {
                try {
                    return org.cometd.JSON.fromJSON(response);
                } catch (x) {
                    this._debug('Could not convert to JSON the following string', '"' + response + '"');
                    throw x;
                }
            }
            if (org.cometd.Utils.isArray(response)) {
                return response;
            }
            if (response === undefined || response === null) {
                return [];
            }
            if (response instanceof Object) {
                return [response];
            }
            throw 'Conversion Error ' + response + ', typeof ' + (typeof response);
        };
        this.accept = function(version, crossDomain, url) {
            throw 'Abstract';
        };
        this.getType = function() {
            return _type;
        };
        this.send = function(envelope, metaConnect) {
            throw 'Abstract';
        };
        this.reset = function() {
            this._debug('Transport', _type, 'reset');
        };
        this.abort = function() {
            this._debug('Transport', _type, 'aborted');
        };
        this.toString = function() {
            return this.getType();
        };
    };
    org.cometd.Transport.derive = function(baseObject) {
        function F() {}
        F.prototype = baseObject;
        return new F();
    };
    org.cometd.RequestTransport = function() {
        var _super = new org.cometd.Transport();
        var _self = org.cometd.Transport.derive(_super);
        var _requestIds = 0;
        var _metaConnectRequest = null;
        var _requests = [];
        var _envelopes = [];
    
        function _coalesceEnvelopes(envelope) {
            while (_envelopes.length > 0) {
                var envelopeAndRequest = _envelopes[0];
                var newEnvelope = envelopeAndRequest[0];
                var newRequest = envelopeAndRequest[1];
                if (newEnvelope.url === envelope.url &&
                    newEnvelope.sync === envelope.sync) {
                    _envelopes.shift();
                    envelope.messages = envelope.messages.concat(newEnvelope.messages);
                    this._debug('Coalesced', newEnvelope.messages.length, 'messages from request', newRequest.id);
                    continue;
                }
                break;
            }
        }
    
        function _transportSend(envelope, request) {
            this.transportSend(envelope, request);
            request.expired = false;
            if (!envelope.sync) {
                var maxDelay = this.getConfiguration().maxNetworkDelay;
                var delay = maxDelay;
                if (request.metaConnect === true) {
                    delay += this.getAdvice().timeout;
                }
                this._debug('Transport', this.getType(), 'waiting at most', delay, 'ms for the response, maxNetworkDelay', maxDelay);
                var self = this;
                request.timeout = this.setTimeout(function() {
                    request.expired = true;
                    var errorMessage = 'Request ' + request.id + ' of transport ' + self.getType() + ' exceeded ' + delay + ' ms max network delay';
                    var failure = {
                        reason: errorMessage
                    };
                    var xhr = request.xhr;
                    failure.httpCode = self.xhrStatus(xhr);
                    self.abortXHR(xhr);
                    self._debug(errorMessage);
                    self.complete(request, false, request.metaConnect);
                    envelope.onFailure(xhr, envelope.messages, failure);
                }, delay);
            }
        }
    
        function _queueSend(envelope) {
            var requestId = ++_requestIds;
            var request = {
                id: requestId,
                metaConnect: false
            };
            if (_requests.length < this.getConfiguration().maxConnections - 1) {
                _requests.push(request);
                _transportSend.call(this, envelope, request);
            } else {
                this._debug('Transport', this.getType(), 'queueing request', requestId, 'envelope', envelope);
                _envelopes.push([envelope, request]);
            }
        }
    
        function _metaConnectComplete(request) {
            var requestId = request.id;
            this._debug('Transport', this.getType(), 'metaConnect complete, request', requestId);
            if (_metaConnectRequest !== null && _metaConnectRequest.id !== requestId) {
                throw 'Longpoll request mismatch, completing request ' + requestId;
            }
            _metaConnectRequest = null;
        }
    
        function _complete(request, success) {
            var index = org.cometd.Utils.inArray(request, _requests);
            if (index >= 0) {
                _requests.splice(index, 1);
            }
            if (_envelopes.length > 0) {
                var envelopeAndRequest = _envelopes.shift();
                var nextEnvelope = envelopeAndRequest[0];
                var nextRequest = envelopeAndRequest[1];
                this._debug('Transport dequeued request', nextRequest.id);
                if (success) {
                    if (this.getConfiguration().autoBatch) {
                        _coalesceEnvelopes.call(this, nextEnvelope);
                    }
                    _queueSend.call(this, nextEnvelope);
                    this._debug('Transport completed request', request.id, nextEnvelope);
                } else {
                    var self = this;
                    this.setTimeout(function() {
                        self.complete(nextRequest, false, nextRequest.metaConnect);
                        var failure = {
                            reason: 'Previous request failed'
                        };
                        var xhr = nextRequest.xhr;
                        failure.httpCode = self.xhrStatus(xhr);
                        nextEnvelope.onFailure(xhr, nextEnvelope.messages, failure);
                    }, 0);
                }
            }
        }
        _self.complete = function(request, success, metaConnect) {
            if (metaConnect) {
                _metaConnectComplete.call(this, request);
            } else {
                _complete.call(this, request, success);
            }
        };
        _self.transportSend = function(envelope, request) {
            throw 'Abstract';
        };
        _self.transportSuccess = function(envelope, request, responses) {
            if (!request.expired) {
                this.clearTimeout(request.timeout);
                this.complete(request, true, request.metaConnect);
                if (responses && responses.length > 0) {
                    envelope.onSuccess(responses);
                } else {
                    envelope.onFailure(request.xhr, envelope.messages, {
                        httpCode: 204
                    });
                }
            }
        };
        _self.transportFailure = function(envelope, request, failure) {
            if (!request.expired) {
                this.clearTimeout(request.timeout);
                this.complete(request, false, request.metaConnect);
                envelope.onFailure(request.xhr, envelope.messages, failure);
            }
        };
    
        function _metaConnectSend(envelope) {
            if (_metaConnectRequest !== null) {
                throw 'Concurrent metaConnect requests not allowed, request id=' + _metaConnectRequest.id + ' not yet completed';
            }
            var requestId = ++_requestIds;
            this._debug('Transport', this.getType(), 'metaConnect send, request', requestId, 'envelope', envelope);
            var request = {
                id: requestId,
                metaConnect: true
            };
            _transportSend.call(this, envelope, request);
            _metaConnectRequest = request;
        }
        _self.send = function(envelope, metaConnect) {
            if (metaConnect) {
                _metaConnectSend.call(this, envelope);
            } else {
                _queueSend.call(this, envelope);
            }
        };
        _self.abort = function() {
            _super.abort();
            for (var i = 0; i < _requests.length; ++i) {
                var request = _requests[i];
                this._debug('Aborting request', request);
                this.abortXHR(request.xhr);
            }
            if (_metaConnectRequest) {
                this._debug('Aborting metaConnect request', _metaConnectRequest);
                this.abortXHR(_metaConnectRequest.xhr);
            }
            this.reset();
        };
        _self.reset = function() {
            _super.reset();
            _metaConnectRequest = null;
            _requests = [];
            _envelopes = [];
        };
        _self.abortXHR = function(xhr) {
            if (xhr) {
                try {
                    xhr.abort();
                } catch (x) {
                    this._debug(x);
                }
            }
        };
        _self.xhrStatus = function(xhr) {
            if (xhr) {
                try {
                    return xhr.status;
                } catch (x) {
                    this._debug(x);
                }
            }
            return -1;
        };
        return _self;
    };
    org.cometd.LongPollingTransport = function() {
        var _super = new org.cometd.RequestTransport();
        var _self = org.cometd.Transport.derive(_super);
        var _supportsCrossDomain = true;
        _self.accept = function(version, crossDomain, url) {
            return _supportsCrossDomain || !crossDomain;
        };
        _self.xhrSend = function(packet) {
            throw 'Abstract';
        };
        _self.transportSend = function(envelope, request) {
            this._debug('Transport', this.getType(), 'sending request', request.id, 'envelope', envelope);
            var self = this;
            try {
                var sameStack = true;
                request.xhr = this.xhrSend({
                    transport: this,
                    url: envelope.url,
                    sync: envelope.sync,
                    headers: this.getConfiguration().requestHeaders,
                    body: org.cometd.JSON.toJSON(envelope.messages),
                    onSuccess: function(response) {
                        self._debug('Transport', self.getType(), 'received response', response);
                        var success = false;
                        try {
                            var received = self.convertToMessages(response);
                            if (received.length === 0) {
                                _supportsCrossDomain = false;
                                self.transportFailure(envelope, request, {
                                    httpCode: 204
                                });
                            } else {
                                success = true;
                                self.transportSuccess(envelope, request, received);
                            }
                        } catch (x) {
                            self._debug(x);
                            if (!success) {
                                _supportsCrossDomain = false;
                                var failure = {
                                    exception: x
                                };
                                failure.httpCode = self.xhrStatus(request.xhr);
                                self.transportFailure(envelope, request, failure);
                            }
                        }
                    },
                    onError: function(reason, exception) {
                        _supportsCrossDomain = false;
                        var failure = {
                            reason: reason,
                            exception: exception
                        };
                        failure.httpCode = self.xhrStatus(request.xhr);
                        if (sameStack) {
                            self.setTimeout(function() {
                                self.transportFailure(envelope, request, failure);
                            }, 0);
                        } else {
                            self.transportFailure(envelope, request, failure);
                        }
                    }
                });
                sameStack = false;
            } catch (x) {
                _supportsCrossDomain = false;
                this.setTimeout(function() {
                    self.transportFailure(envelope, request, {
                        exception: x
                    });
                }, 0);
            }
        };
        _self.reset = function() {
            _super.reset();
            _supportsCrossDomain = true;
        };
        return _self;
    };
    org.cometd.CallbackPollingTransport = function() {
        var _super = new org.cometd.RequestTransport();
        var _self = org.cometd.Transport.derive(_super);
        var _maxLength = 2000;
        _self.accept = function(version, crossDomain, url) {
            return true;
        };
        _self.jsonpSend = function(packet) {
            throw 'Abstract';
        };
        _self.transportSend = function(envelope, request) {
            var self = this;
            var start = 0;
            var length = envelope.messages.length;
            var lengths = [];
            while (length > 0) {
                var json = org.cometd.JSON.toJSON(envelope.messages.slice(start, start + length));
                var urlLength = envelope.url.length + encodeURI(json).length;
                if (urlLength > _maxLength) {
                    if (length === 1) {
                        this.setTimeout(function() {
                            self.transportFailure(envelope, request, {
                                reason: 'Bayeux message too big, max is ' + _maxLength
                            });
                        }, 0);
                        return;
                    }
                    --length;
                    continue;
                }
                lengths.push(length);
                start += length;
                length = envelope.messages.length - start;
            }
            var envelopeToSend = envelope;
            if (lengths.length > 1) {
                var begin = 0;
                var end = lengths[0];
                this._debug('Transport', this.getType(), 'split', envelope.messages.length, 'messages into', lengths.join(' + '));
                envelopeToSend = this._mixin(false, {}, envelope);
                envelopeToSend.messages = envelope.messages.slice(begin, end);
                envelopeToSend.onSuccess = envelope.onSuccess;
                envelopeToSend.onFailure = envelope.onFailure;
                for (var i = 1; i < lengths.length; ++i) {
                    var nextEnvelope = this._mixin(false, {}, envelope);
                    begin = end;
                    end += lengths[i];
                    nextEnvelope.messages = envelope.messages.slice(begin, end);
                    nextEnvelope.onSuccess = envelope.onSuccess;
                    nextEnvelope.onFailure = envelope.onFailure;
                    this.send(nextEnvelope, request.metaConnect);
                }
            }
            this._debug('Transport', this.getType(), 'sending request', request.id, 'envelope', envelopeToSend);
            try {
                var sameStack = true;
                this.jsonpSend({
                    transport: this,
                    url: envelopeToSend.url,
                    sync: envelopeToSend.sync,
                    headers: this.getConfiguration().requestHeaders,
                    body: org.cometd.JSON.toJSON(envelopeToSend.messages),
                    onSuccess: function(responses) {
                        var success = false;
                        try {
                            var received = self.convertToMessages(responses);
                            if (received.length === 0) {
                                self.transportFailure(envelopeToSend, request, {
                                    httpCode: 204
                                });
                            } else {
                                success = true;
                                self.transportSuccess(envelopeToSend, request, received);
                            }
                        } catch (x) {
                            self._debug(x);
                            if (!success) {
                                self.transportFailure(envelopeToSend, request, {
                                    exception: x
                                });
                            }
                        }
                    },
                    onError: function(reason, exception) {
                        var failure = {
                            reason: reason,
                            exception: exception
                        };
                        if (sameStack) {
                            self.setTimeout(function() {
                                self.transportFailure(envelopeToSend, request, failure);
                            }, 0);
                        } else {
                            self.transportFailure(envelopeToSend, request, failure);
                        }
                    }
                });
                sameStack = false;
            } catch (xx) {
                this.setTimeout(function() {
                    self.transportFailure(envelopeToSend, request, {
                        exception: xx
                    });
                }, 0);
            }
        };
        return _self;
    };
    org.cometd.WebSocketTransport = function() {
        var _super = new org.cometd.Transport();
        var _self = org.cometd.Transport.derive(_super);
        var _cometd;
        var _webSocketSupported = true;
        var _webSocketConnected = false;
        var _stickyReconnect = true;
        var _envelopes = {};
        var _timeouts = {};
        var _connecting = false;
        var _webSocket = null;
        var _connected = false;
        var _successCallback = null;
        _self.reset = function() {
            _super.reset();
            _webSocketSupported = true;
            _webSocketConnected = false;
            _stickyReconnect = true;
            _envelopes = {};
            _timeouts = {};
            _connecting = false;
            _webSocket = null;
            _connected = false;
            _successCallback = null;
        };
    
        function _websocketConnect() {
            if (_connecting) {
                return;
            }
            _connecting = true;
            var url = _cometd.getURL().replace(/^http/, 'ws');
            this._debug('Transport', this.getType(), 'connecting to URL', url);
            try {
                var protocol = _cometd.getConfiguration().protocol;
                var webSocket = protocol ? new org.cometd.WebSocket(url, protocol) : new org.cometd.WebSocket(url);
            } catch (x) {
                _webSocketSupported = false;
                this._debug('Exception while creating WebSocket object', x);
                throw x;
            }
            _stickyReconnect = _cometd.getConfiguration().stickyReconnect !== false;
            var self = this;
            var connectTimer = null;
            var connectTimeout = _cometd.getConfiguration().connectTimeout;
            if (connectTimeout > 0) {
                connectTimer = this.setTimeout(function() {
                    connectTimer = null;
                    self._debug('Transport', self.getType(), 'timed out while connecting to URL', url, ':', connectTimeout, 'ms');
                    var event = {
                        code: 1000,
                        reason: 'Connect Timeout'
                    };
                    self.webSocketClose(webSocket, event.code, event.reason);
                    self.onClose(webSocket, event);
                }, connectTimeout);
            }
            var onopen = function() {
                self._debug('WebSocket opened', webSocket);
                _connecting = false;
                if (connectTimer) {
                    self.clearTimeout(connectTimer);
                    connectTimer = null;
                }
                if (_webSocket) {
                    _cometd._warn('Closing Extra WebSocket Connections', webSocket, _webSocket);
                    self.webSocketClose(webSocket, 1000, 'Extra Connection');
                } else {
                    self.onOpen(webSocket);
                }
            };
            var onclose = function(event) {
                event = event || {
                    code: 1000
                };
                self._debug('WebSocket closing', webSocket, event);
                _connecting = false;
                if (connectTimer) {
                    self.clearTimeout(connectTimer);
                    connectTimer = null;
                }
                if (_webSocket !== null && webSocket !== _webSocket) {
                    self._debug('Closed Extra WebSocket Connection', webSocket);
                } else {
                    self.onClose(webSocket, event);
                }
            };
            var onmessage = function(message) {
                self._debug('WebSocket message', message, webSocket);
                if (webSocket !== _webSocket) {
                    _cometd._warn('Extra WebSocket Connections', webSocket, _webSocket);
                }
                self.onMessage(webSocket, message);
            };
            webSocket.onopen = onopen;
            webSocket.onclose = onclose;
            webSocket.onerror = function() {
                onclose({
                    code: 1002,
                    reason: 'Error'
                });
            };
            webSocket.onmessage = onmessage;
            this._debug('Transport', this.getType(), 'configured callbacks on', webSocket);
        }
    
        function _webSocketSend(webSocket, envelope, metaConnect) {
            var json = org.cometd.JSON.toJSON(envelope.messages);
            webSocket.send(json);
            this._debug('Transport', this.getType(), 'sent', envelope, 'metaConnect =', metaConnect);
            var maxDelay = this.getConfiguration().maxNetworkDelay;
            var delay = maxDelay;
            if (metaConnect) {
                delay += this.getAdvice().timeout;
                _connected = true;
            }
            var self = this;
            var messageIds = [];
            for (var i = 0; i < envelope.messages.length; ++i) {
                (function() {
                    var message = envelope.messages[i];
                    if (message.id) {
                        messageIds.push(message.id);
                        _timeouts[message.id] = this.setTimeout(function() {
                            self._debug('Transport', self.getType(), 'timing out message', message.id, 'after', delay, 'on', webSocket);
                            var event = {
                                code: 1000,
                                reason: 'Message Timeout'
                            };
                            self.webSocketClose(webSocket, event.code, event.reason);
                            self.onClose(webSocket, event);
                        }, delay);
                    }
                })();
            }
            this._debug('Transport', this.getType(), 'waiting at most', delay, 'ms for messages', messageIds, 'maxNetworkDelay', maxDelay, ', timeouts:', _timeouts);
        }
    
        function _send(webSocket, envelope, metaConnect) {
            try {
                if (webSocket === null) {
                    _websocketConnect.call(this);
                } else {
                    _webSocketSend.call(this, webSocket, envelope, metaConnect);
                }
            } catch (x) {
                this.setTimeout(function() {
                    envelope.onFailure(webSocket, envelope.messages, {
                        exception: x
                    });
                }, 0);
            }
        }
        _self.onOpen = function(webSocket) {
            this._debug('Transport', this.getType(), 'opened', webSocket);
            _webSocket = webSocket;
            _webSocketConnected = true;
            this._debug('Sending pending messages', _envelopes);
            for (var key in _envelopes) {
                var element = _envelopes[key];
                var envelope = element[0];
                var metaConnect = element[1];
                _successCallback = envelope.onSuccess;
                _webSocketSend.call(this, webSocket, envelope, metaConnect);
            }
        };
        _self.onMessage = function(webSocket, wsMessage) {
            this._debug('Transport', this.getType(), 'received websocket message', wsMessage, webSocket);
            var close = false;
            var messages = this.convertToMessages(wsMessage.data);
            var messageIds = [];
            for (var i = 0; i < messages.length; ++i) {
                var message = messages[i];
                if (/^\/meta\//.test(message.channel) || message.successful !== undefined) {
                    if (message.id) {
                        messageIds.push(message.id);
                        var timeout = _timeouts[message.id];
                        if (timeout) {
                            this.clearTimeout(timeout);
                            delete _timeouts[message.id];
                            this._debug('Transport', this.getType(), 'removed timeout for message', message.id, ', timeouts', _timeouts);
                        }
                    }
                }
                if ('/meta/connect' === message.channel) {
                    _connected = false;
                }
                if ('/meta/disconnect' === message.channel && !_connected) {
                    close = true;
                }
            }
            var removed = false;
            for (var j = 0; j < messageIds.length; ++j) {
                var id = messageIds[j];
                for (var key in _envelopes) {
                    var ids = key.split(',');
                    var index = org.cometd.Utils.inArray(id, ids);
                    if (index >= 0) {
                        removed = true;
                        ids.splice(index, 1);
                        var envelope = _envelopes[key][0];
                        var metaConnect = _envelopes[key][1];
                        delete _envelopes[key];
                        if (ids.length > 0) {
                            _envelopes[ids.join(',')] = [envelope, metaConnect];
                        }
                        break;
                    }
                }
            }
            if (removed) {
                this._debug('Transport', this.getType(), 'removed envelope, envelopes', _envelopes);
            }
            _successCallback.call(this, messages);
            if (close) {
                this.webSocketClose(webSocket, 1000, 'Disconnect');
            }
        };
        _self.onClose = function(webSocket, event) {
            this._debug('Transport', this.getType(), 'closed', webSocket, event);
            _webSocketSupported = _stickyReconnect && _webSocketConnected;
            for (var id in _timeouts) {
                this.clearTimeout(_timeouts[id]);
            }
            _timeouts = {};
            for (var key in _envelopes) {
                var envelope = _envelopes[key][0];
                var metaConnect = _envelopes[key][1];
                if (metaConnect) {
                    _connected = false;
                }
                envelope.onFailure(webSocket, envelope.messages, {
                    websocketCode: event.code,
                    reason: event.reason
                });
            }
            _envelopes = {};
            _webSocket = null;
        };
        _self.registered = function(type, cometd) {
            _super.registered(type, cometd);
            _cometd = cometd;
        };
        _self.accept = function(version, crossDomain, url) {
            return _webSocketSupported && !!org.cometd.WebSocket && _cometd.websocketEnabled !== false;
        };
        _self.send = function(envelope, metaConnect) {
            this._debug('Transport', this.getType(), 'sending', envelope, 'metaConnect =', metaConnect);
            var messageIds = [];
            for (var i = 0; i < envelope.messages.length; ++i) {
                var message = envelope.messages[i];
                if (message.id) {
                    messageIds.push(message.id);
                }
            }
            _envelopes[messageIds.join(',')] = [envelope, metaConnect];
            this._debug('Transport', this.getType(), 'stored envelope, envelopes', _envelopes);
            _send.call(this, _webSocket, envelope, metaConnect);
        };
        _self.webSocketClose = function(webSocket, code, reason) {
            try {
                webSocket.close(code, reason);
            } catch (x) {
                this._debug(x);
            }
        };
        _self.abort = function() {
            _super.abort();
            if (_webSocket) {
                var event = {
                    code: 1001,
                    reason: 'Abort'
                };
                this.webSocketClose(_webSocket, event.code, event.reason);
                this.onClose(_webSocket, event);
            }
            this.reset();
        };
        return _self;
    };
    org.cometd.Cometd = function(name) {
        var _cometd = this;
        var _name = name || 'default';
        var _crossDomain = false;
        var _transports = new org.cometd.TransportRegistry();
        var _transport;
        var _status = 'disconnected';
        var _messageId = 0;
        var _clientId = null;
        var _batch = 0;
        var _messageQueue = [];
        var _internalBatch = false;
        var _listeners = {};
        var _backoff = 0;
        var _scheduledSend = null;
        var _extensions = [];
        var _advice = {};
        var _handshakeProps;
        var _handshakeCallback;
        var _callbacks = {};
        var _reestablish = false;
        var _connected = false;
        var _config = {
            protocol: null,
            stickyReconnect: true,
            connectTimeout: 0,
            maxConnections: 2,
            backoffIncrement: 1000,
            maxBackoff: 60000,
            logLevel: 'info',
            reverseIncomingExtensions: true,
            maxNetworkDelay: 10000,
            requestHeaders: {},
            appendMessageTypeToURL: true,
            autoBatch: false,
            advice: {
                timeout: 60000,
                interval: 0,
                reconnect: 'retry'
            }
        };
    
        function _fieldValue(object, name) {
            try {
                return object[name];
            } catch (x) {
                return undefined;
            }
        }
        this._mixin = function(deep, target, objects) {
            var result = target || {};
            for (var i = 2; i < arguments.length; ++i) {
                var object = arguments[i];
                if (object === undefined || object === null) {
                    continue;
                }
                for (var propName in object) {
                    var prop = _fieldValue(object, propName);
                    var targ = _fieldValue(result, propName);
                    if (prop === target) {
                        continue;
                    }
                    if (prop === undefined) {
                        continue;
                    }
                    if (deep && typeof prop === 'object' && prop !== null) {
                        if (prop instanceof Array) {
                            result[propName] = this._mixin(deep, targ instanceof Array ? targ : [], prop);
                        } else {
                            var source = typeof targ === 'object' && !(targ instanceof Array) ? targ : {};
                            result[propName] = this._mixin(deep, source, prop);
                        }
                    } else {
                        result[propName] = prop;
                    }
                }
            }
            return result;
        };
    
        function _isString(value) {
            return org.cometd.Utils.isString(value);
        }
    
        function _isFunction(value) {
            if (value === undefined || value === null) {
                return false;
            }
            return typeof value === 'function';
        }
    
        function _log(level, args) {
            if (window.console) {
                var logger = window.console[level];
                if (_isFunction(logger)) {
                    logger.apply(window.console, args);
                }
            }
        }
        this._warn = function() {
            _log('warn', arguments);
        };
        this._info = function() {
            if (_config.logLevel !== 'warn') {
                _log('info', arguments);
            }
        };
        this._debug = function() {
            if (_config.logLevel === 'debug') {
                _log('debug', arguments);
            }
        };
        this._isCrossDomain = function(hostAndPort) {
            return hostAndPort && hostAndPort !== window.location.host;
        };
    
        function _configure(configuration) {
            _cometd._debug('Configuring cometd object with', configuration);
            if (_isString(configuration)) {
                configuration = {
                    url: configuration
                };
            }
            if (!configuration) {
                configuration = {};
            }
            _config = _cometd._mixin(false, _config, configuration);
            var url = _cometd.getURL();
            if (!url) {
                throw 'Missing required configuration parameter \'url\' specifying the Bayeux server URL';
            }
            var urlParts = /(^https?:\/\/)?(((\[[^\]]+\])|([^:\/\?#]+))(:(\d+))?)?([^\?#]*)(.*)?/.exec(url);
            var hostAndPort = urlParts[2];
            var uri = urlParts[8];
            var afterURI = urlParts[9];
            _crossDomain = _cometd._isCrossDomain(hostAndPort);
            if (_config.appendMessageTypeToURL) {
                if (afterURI !== undefined && afterURI.length > 0) {
                    _cometd._info('Appending message type to URI ' + uri + afterURI + ' is not supported, disabling \'appendMessageTypeToURL\' configuration');
                    _config.appendMessageTypeToURL = false;
                } else {
                    var uriSegments = uri.split('/');
                    var lastSegmentIndex = uriSegments.length - 1;
                    if (uri.match(/\/$/)) {
                        lastSegmentIndex -= 1;
                    }
                    if (uriSegments[lastSegmentIndex].indexOf('.') >= 0) {
                        _cometd._info('Appending message type to URI ' + uri + ' is not supported, disabling \'appendMessageTypeToURL\' configuration');
                        _config.appendMessageTypeToURL = false;
                    }
                }
            }
        }
    
        function _removeListener(subscription) {
            if (subscription) {
                var subscriptions = _listeners[subscription.channel];
                if (subscriptions && subscriptions[subscription.id]) {
                    delete subscriptions[subscription.id];
                    _cometd._debug('Removed', subscription.listener ? 'listener' : 'subscription', subscription);
                }
            }
        }
    
        function _removeSubscription(subscription) {
            if (subscription && !subscription.listener) {
                _removeListener(subscription);
            }
        }
    
        function _clearSubscriptions() {
            for (var channel in _listeners) {
                var subscriptions = _listeners[channel];
                if (subscriptions) {
                    for (var i = 0; i < subscriptions.length; ++i) {
                        _removeSubscription(subscriptions[i]);
                    }
                }
            }
        }
    
        function _setStatus(newStatus) {
            if (_status !== newStatus) {
                _cometd._debug('Status', _status, '->', newStatus);
                _status = newStatus;
            }
        }
    
        function _isDisconnected() {
            return _status === 'disconnecting' || _status === 'disconnected';
        }
    
        function _nextMessageId() {
            return ++_messageId;
        }
    
        function _applyExtension(scope, callback, name, message, outgoing) {
            try {
                return callback.call(scope, message);
            } catch (x) {
                _cometd._debug('Exception during execution of extension', name, x);
                var exceptionCallback = _cometd.onExtensionException;
                if (_isFunction(exceptionCallback)) {
                    _cometd._debug('Invoking extension exception callback', name, x);
                    try {
                        exceptionCallback.call(_cometd, x, name, outgoing, message);
                    } catch (xx) {
                        _cometd._info('Exception during execution of exception callback in extension', name, xx);
                    }
                }
                return message;
            }
        }
    
        function _applyIncomingExtensions(message) {
            for (var i = 0; i < _extensions.length; ++i) {
                if (message === undefined || message === null) {
                    break;
                }
                var index = _config.reverseIncomingExtensions ? _extensions.length - 1 - i : i;
                var extension = _extensions[index];
                var callback = extension.extension.incoming;
                if (_isFunction(callback)) {
                    var result = _applyExtension(extension.extension, callback, extension.name, message, false);
                    message = result === undefined ? message : result;
                }
            }
            return message;
        }
    
        function _applyOutgoingExtensions(message) {
            for (var i = 0; i < _extensions.length; ++i) {
                if (message === undefined || message === null) {
                    break;
                }
                var extension = _extensions[i];
                var callback = extension.extension.outgoing;
                if (_isFunction(callback)) {
                    var result = _applyExtension(extension.extension, callback, extension.name, message, true);
                    message = result === undefined ? message : result;
                }
            }
            return message;
        }
    
        function _notify(channel, message) {
            var subscriptions = _listeners[channel];
            if (subscriptions && subscriptions.length > 0) {
                for (var i = 0; i < subscriptions.length; ++i) {
                    var subscription = subscriptions[i];
                    if (subscription) {
                        try {
                            subscription.callback.call(subscription.scope, message);
                        } catch (x) {
                            _cometd._debug('Exception during notification', subscription, message, x);
                            var listenerCallback = _cometd.onListenerException;
                            if (_isFunction(listenerCallback)) {
                                _cometd._debug('Invoking listener exception callback', subscription, x);
                                try {
                                    listenerCallback.call(_cometd, x, subscription, subscription.listener, message);
                                } catch (xx) {
                                    _cometd._info('Exception during execution of listener callback', subscription, xx);
                                }
                            }
                        }
                    }
                }
            }
        }
    
        function _notifyListeners(channel, message) {
            _notify(channel, message);
            var channelParts = channel.split('/');
            var last = channelParts.length - 1;
            for (var i = last; i > 0; --i) {
                var channelPart = channelParts.slice(0, i).join('/') + '/*';
                if (i === last) {
                    _notify(channelPart, message);
                }
                channelPart += '*';
                _notify(channelPart, message);
            }
        }
    
        function _cancelDelayedSend() {
            if (_scheduledSend !== null) {
                org.cometd.Utils.clearTimeout(_scheduledSend);
            }
            _scheduledSend = null;
        }
    
        function _delayedSend(operation) {
            _cancelDelayedSend();
            var delay = _advice.interval + _backoff;
            _cometd._debug('Function scheduled in', delay, 'ms, interval =', _advice.interval, 'backoff =', _backoff, operation);
            _scheduledSend = org.cometd.Utils.setTimeout(_cometd, operation, delay);
        }
        var _handleMessages;
        var _handleFailure;
    
        function _send(sync, messages, longpoll, extraPath) {
            for (var i = 0; i < messages.length; ++i) {
                var message = messages[i];
                var messageId = '' + _nextMessageId();
                message.id = messageId;
                if (_clientId) {
                    message.clientId = _clientId;
                }
                var callback = undefined;
                if (_isFunction(message._callback)) {
                    callback = message._callback;
                    delete message._callback;
                }
                message = _applyOutgoingExtensions(message);
                if (message !== undefined && message !== null) {
                    message.id = messageId;
                    messages[i] = message;
                    if (callback) {
                        _callbacks[messageId] = callback;
                    }
                } else {
                    messages.splice(i--, 1);
                }
            }
            if (messages.length === 0) {
                return;
            }
            var url = _cometd.getURL();
            if (_config.appendMessageTypeToURL) {
                if (!url.match(/\/$/)) {
                    url = url + '/';
                }
                if (extraPath) {
                    url = url + extraPath;
                }
            }
            var envelope = {
                url: url,
                sync: sync,
                messages: messages,
                onSuccess: function(rcvdMessages) {
                    try {
                        _handleMessages.call(_cometd, rcvdMessages);
                    } catch (x) {
                        _cometd._debug('Exception during handling of messages', x);
                    }
                },
                onFailure: function(conduit, messages, failure) {
                    try {
                        failure.connectionType = _cometd.getTransport().getType();
                        _handleFailure.call(_cometd, conduit, messages, failure);
                    } catch (x) {
                        _cometd._debug('Exception during handling of failure', x);
                    }
                }
            };
            _cometd._debug('Send', envelope);
            _transport.send(envelope, longpoll);
        }
    
        function _queueSend(message) {
            if (_batch > 0 || _internalBatch === true) {
                _messageQueue.push(message);
            } else {
                _send(false, [message], false);
            }
        }
        this.send = _queueSend;
    
        function _resetBackoff() {
            _backoff = 0;
        }
    
        function _increaseBackoff() {
            if (_backoff < _config.maxBackoff) {
                _backoff += _config.backoffIncrement;
            }
        }
    
        function _startBatch() {
            ++_batch;
        }
    
        function _flushBatch() {
            var messages = _messageQueue;
            _messageQueue = [];
            if (messages.length > 0) {
                _send(false, messages, false);
            }
        }
    
        function _endBatch() {
            --_batch;
            if (_batch < 0) {
                throw 'Calls to startBatch() and endBatch() are not paired';
            }
            if (_batch === 0 && !_isDisconnected() && !_internalBatch) {
                _flushBatch();
            }
        }
    
        function _connect() {
            if (!_isDisconnected()) {
                var message = {
                    channel: '/meta/connect',
                    connectionType: _transport.getType()
                };
                if (!_connected) {
                    message.advice = {
                        timeout: 0
                    };
                }
                _setStatus('connecting');
                _cometd._debug('Connect sent', message);
                _send(false, [message], true, 'connect');
                _setStatus('connected');
            }
        }
    
        function _delayedConnect() {
            _setStatus('connecting');
            _delayedSend(function() {
                _connect();
            });
        }
    
        function _updateAdvice(newAdvice) {
            if (newAdvice) {
                _advice = _cometd._mixin(false, {}, _config.advice, newAdvice);
                _cometd._debug('New advice', _advice);
            }
        }
    
        function _disconnect(abort) {
            _cancelDelayedSend();
            if (abort) {
                _transport.abort();
            }
            _clientId = null;
            _setStatus('disconnected');
            _batch = 0;
            _resetBackoff();
            _transport = null;
            if (_messageQueue.length > 0) {
                _handleFailure.call(_cometd, undefined, _messageQueue, {
                    reason: 'Disconnected'
                });
                _messageQueue = [];
            }
        }
    
        function _notifyTransportFailure(oldTransport, newTransport, failure) {
            var callback = _cometd.onTransportFailure;
            if (_isFunction(callback)) {
                _cometd._debug('Invoking transport failure callback', oldTransport, newTransport, failure);
                try {
                    callback.call(_cometd, oldTransport, newTransport, failure);
                } catch (x) {
                    _cometd._info('Exception during execution of transport failure callback', x);
                }
            }
        }
    
        function _handshake(handshakeProps, handshakeCallback) {
            if (_isFunction(handshakeProps)) {
                handshakeCallback = handshakeProps;
                handshakeProps = undefined;
            }
            _clientId = null;
            _clearSubscriptions();
            if (_isDisconnected()) {
                _transports.reset();
                _updateAdvice(_config.advice);
            } else {
                _updateAdvice(_cometd._mixin(false, _advice, {
                    reconnect: 'retry'
                }));
            }
            _batch = 0;
            _internalBatch = true;
            _handshakeProps = handshakeProps;
            _handshakeCallback = handshakeCallback;
            var version = '1.0';
            var url = _cometd.getURL();
            var transportTypes = _transports.findTransportTypes(version, _crossDomain, url);
            var bayeuxMessage = {
                version: version,
                minimumVersion: version,
                channel: '/meta/handshake',
                supportedConnectionTypes: transportTypes,
                _callback: handshakeCallback,
                advice: {
                    timeout: _advice.timeout,
                    interval: _advice.interval
                }
            };
            var message = _cometd._mixin(false, {}, _handshakeProps, bayeuxMessage);
            if (!_transport) {
                _transport = _transports.negotiateTransport(transportTypes, version, _crossDomain, url);
                if (!_transport) {
                    var failure = 'Could not find initial transport among: ' + _transports.getTransportTypes();
                    _cometd._warn(failure);
                    throw failure;
                }
            }
            _cometd._debug('Initial transport is', _transport.getType());
            _setStatus('handshaking');
            _cometd._debug('Handshake sent', message);
            _send(false, [message], false, 'handshake');
        }
    
        function _delayedHandshake() {
            _setStatus('handshaking');
            _internalBatch = true;
            _delayedSend(function() {
                _handshake(_handshakeProps, _handshakeCallback);
            });
        }
    
        function _handleCallback(message) {
            var callback = _callbacks[message.id];
            if (_isFunction(callback)) {
                delete _callbacks[message.id];
                callback.call(_cometd, message);
            }
        }
    
        function _failHandshake(message) {
            _handleCallback(message);
            _notifyListeners('/meta/handshake', message);
            _notifyListeners('/meta/unsuccessful', message);
            var retry = !_isDisconnected() && _advice.reconnect !== 'none';
            if (retry) {
                _increaseBackoff();
                _delayedHandshake();
            } else {
                _disconnect(false);
            }
        }
    
        function _handshakeResponse(message) {
            if (message.successful) {
                _clientId = message.clientId;
                var url = _cometd.getURL();
                var newTransport = _transports.negotiateTransport(message.supportedConnectionTypes, message.version, _crossDomain, url);
                if (newTransport === null) {
                    var failure = 'Could not negotiate transport with server; client=[' +
                        _transports.findTransportTypes(message.version, _crossDomain, url) +
                        '], server=[' + message.supportedConnectionTypes + ']';
                    var oldTransport = _cometd.getTransport();
                    _notifyTransportFailure(oldTransport.getType(), null, {
                        reason: failure,
                        connectionType: oldTransport.getType(),
                        transport: oldTransport
                    });
                    _cometd._warn(failure);
                    _transport.reset();
                    _failHandshake(message);
                    return;
                } else if (_transport !== newTransport) {
                    _cometd._debug('Transport', _transport.getType(), '->', newTransport.getType());
                    _transport = newTransport;
                }
                _internalBatch = false;
                _flushBatch();
                message.reestablish = _reestablish;
                _reestablish = true;
                _handleCallback(message);
                _notifyListeners('/meta/handshake', message);
                var action = _isDisconnected() ? 'none' : _advice.reconnect;
                switch (action) {
                    case 'retry':
                        _resetBackoff();
                        _delayedConnect();
                        break;
                    case 'none':
                        _disconnect(false);
                        break;
                    default:
                        throw 'Unrecognized advice action ' + action;
                }
            } else {
                _failHandshake(message);
            }
        }
    
        function _handshakeFailure(message) {
            var version = '1.0';
            var url = _cometd.getURL();
            var oldTransport = _cometd.getTransport();
            var transportTypes = _transports.findTransportTypes(version, _crossDomain, url);
            var newTransport = _transports.negotiateTransport(transportTypes, version, _crossDomain, url);
            if (!newTransport) {
                _notifyTransportFailure(oldTransport.getType(), null, message.failure);
                _cometd._warn('Could not negotiate transport; client=[' + transportTypes + ']');
                _transport.reset();
                _failHandshake(message);
            } else {
                _cometd._debug('Transport', oldTransport.getType(), '->', newTransport.getType());
                _notifyTransportFailure(oldTransport.getType(), newTransport.getType(), message.failure);
                _failHandshake(message);
                _transport = newTransport;
            }
        }
    
        function _failConnect(message) {
            _notifyListeners('/meta/connect', message);
            _notifyListeners('/meta/unsuccessful', message);
            var action = _isDisconnected() ? 'none' : _advice.reconnect;
            switch (action) {
                case 'retry':
                    _delayedConnect();
                    _increaseBackoff();
                    break;
                case 'handshake':
                    _transports.reset();
                    _resetBackoff();
                    _delayedHandshake();
                    break;
                case 'none':
                    _disconnect(false);
                    break;
                default:
                    throw 'Unrecognized advice action' + action;
            }
        }
    
        function _connectResponse(message) {
            _connected = message.successful;
            if (_connected) {
                _notifyListeners('/meta/connect', message);
                var action = _isDisconnected() ? 'none' : _advice.reconnect;
                switch (action) {
                    case 'retry':
                        _resetBackoff();
                        _delayedConnect();
                        break;
                    case 'none':
                        _disconnect(false);
                        break;
                    default:
                        throw 'Unrecognized advice action ' + action;
                }
            } else {
                _failConnect(message);
            }
        }
    
        function _connectFailure(message) {
            _connected = false;
            _failConnect(message);
        }
    
        function _failDisconnect(message) {
            _disconnect(true);
            _handleCallback(message);
            _notifyListeners('/meta/disconnect', message);
            _notifyListeners('/meta/unsuccessful', message);
        }
    
        function _disconnectResponse(message) {
            if (message.successful) {
                _disconnect(false);
                _handleCallback(message);
                _notifyListeners('/meta/disconnect', message);
            } else {
                _failDisconnect(message);
            }
        }
    
        function _disconnectFailure(message) {
            _failDisconnect(message);
        }
    
        function _failSubscribe(message) {
            var subscriptions = _listeners[message.subscription];
            if (subscriptions) {
                for (var i = subscriptions.length - 1; i >= 0; --i) {
                    var subscription = subscriptions[i];
                    if (subscription && !subscription.listener) {
                        delete subscriptions[i];
                        _cometd._debug('Removed failed subscription', subscription);
                        break;
                    }
                }
            }
            _handleCallback(message);
            _notifyListeners('/meta/subscribe', message);
            _notifyListeners('/meta/unsuccessful', message);
        }
    
        function _subscribeResponse(message) {
            if (message.successful) {
                _handleCallback(message);
                _notifyListeners('/meta/subscribe', message);
            } else {
                _failSubscribe(message);
            }
        }
    
        function _subscribeFailure(message) {
            _failSubscribe(message);
        }
    
        function _failUnsubscribe(message) {
            _handleCallback(message);
            _notifyListeners('/meta/unsubscribe', message);
            _notifyListeners('/meta/unsuccessful', message);
        }
    
        function _unsubscribeResponse(message) {
            if (message.successful) {
                _handleCallback(message);
                _notifyListeners('/meta/unsubscribe', message);
            } else {
                _failUnsubscribe(message);
            }
        }
    
        function _unsubscribeFailure(message) {
            _failUnsubscribe(message);
        }
    
        function _failMessage(message) {
            _handleCallback(message);
            _notifyListeners('/meta/publish', message);
            _notifyListeners('/meta/unsuccessful', message);
        }
    
        function _messageResponse(message) {
            if (message.successful === undefined) {
                if (message.data !== undefined) {
                    _notifyListeners(message.channel, message);
                } else {
                    _cometd._warn('Unknown Bayeux Message', message);
                }
            } else {
                if (message.successful) {
                    _handleCallback(message);
                    _notifyListeners('/meta/publish', message);
                } else {
                    _failMessage(message);
                }
            }
        }
    
        function _messageFailure(failure) {
            _failMessage(failure);
        }
    
        function _receive(message) {
            message = _applyIncomingExtensions(message);
            if (message === undefined || message === null) {
                return;
            }
            _updateAdvice(message.advice);
            var channel = message.channel;
            switch (channel) {
                case '/meta/handshake':
                    _handshakeResponse(message);
                    break;
                case '/meta/connect':
                    _connectResponse(message);
                    break;
                case '/meta/disconnect':
                    _disconnectResponse(message);
                    break;
                case '/meta/subscribe':
                    _subscribeResponse(message);
                    break;
                case '/meta/unsubscribe':
                    _unsubscribeResponse(message);
                    break;
                default:
                    _messageResponse(message);
                    break;
            }
        }
        this.receive = _receive;
        _handleMessages = function(rcvdMessages) {
            _cometd._debug('Received', rcvdMessages);
            for (var i = 0; i < rcvdMessages.length; ++i) {
                var message = rcvdMessages[i];
                _receive(message);
            }
        };
        _handleFailure = function(conduit, messages, failure) {
            _cometd._debug('handleFailure', conduit, messages, failure);
            failure.transport = conduit;
            for (var i = 0; i < messages.length; ++i) {
                var message = messages[i];
                var failureMessage = {
                    id: message.id,
                    successful: false,
                    channel: message.channel,
                    failure: failure
                };
                failure.message = message;
                switch (message.channel) {
                    case '/meta/handshake':
                        _handshakeFailure(failureMessage);
                        break;
                    case '/meta/connect':
                        _connectFailure(failureMessage);
                        break;
                    case '/meta/disconnect':
                        _disconnectFailure(failureMessage);
                        break;
                    case '/meta/subscribe':
                        failureMessage.subscription = message.subscription;
                        _subscribeFailure(failureMessage);
                        break;
                    case '/meta/unsubscribe':
                        failureMessage.subscription = message.subscription;
                        _unsubscribeFailure(failureMessage);
                        break;
                    default:
                        _messageFailure(failureMessage);
                        break;
                }
            }
        };
    
        function _hasSubscriptions(channel) {
            var subscriptions = _listeners[channel];
            if (subscriptions) {
                for (var i = 0; i < subscriptions.length; ++i) {
                    if (subscriptions[i]) {
                        return true;
                    }
                }
            }
            return false;
        }
    
        function _resolveScopedCallback(scope, callback) {
            var delegate = {
                scope: scope,
                method: callback
            };
            if (_isFunction(scope)) {
                delegate.scope = undefined;
                delegate.method = scope;
            } else {
                if (_isString(callback)) {
                    if (!scope) {
                        throw 'Invalid scope ' + scope;
                    }
                    delegate.method = scope[callback];
                    if (!_isFunction(delegate.method)) {
                        throw 'Invalid callback ' + callback + ' for scope ' + scope;
                    }
                } else if (!_isFunction(callback)) {
                    throw 'Invalid callback ' + callback;
                }
            }
            return delegate;
        }
    
        function _addListener(channel, scope, callback, isListener) {
            var delegate = _resolveScopedCallback(scope, callback);
            _cometd._debug('Adding', isListener ? 'listener' : 'subscription', 'on', channel, 'with scope', delegate.scope, 'and callback', delegate.method);
            var subscription = {
                channel: channel,
                scope: delegate.scope,
                callback: delegate.method,
                listener: isListener
            };
            var subscriptions = _listeners[channel];
            if (!subscriptions) {
                subscriptions = [];
                _listeners[channel] = subscriptions;
            }
            subscription.id = subscriptions.push(subscription) - 1;
            _cometd._debug('Added', isListener ? 'listener' : 'subscription', subscription);
            subscription[0] = channel;
            subscription[1] = subscription.id;
            return subscription;
        }
        this.registerTransport = function(type, transport, index) {
            var result = _transports.add(type, transport, index);
            if (result) {
                this._debug('Registered transport', type);
                if (_isFunction(transport.registered)) {
                    transport.registered(type, this);
                }
            }
            return result;
        };
        this.getTransportTypes = function() {
            return _transports.getTransportTypes();
        };
        this.unregisterTransport = function(type) {
            var transport = _transports.remove(type);
            if (transport !== null) {
                this._debug('Unregistered transport', type);
                if (_isFunction(transport.unregistered)) {
                    transport.unregistered();
                }
            }
            return transport;
        };
        this.unregisterTransports = function() {
            _transports.clear();
        };
        this.findTransport = function(name) {
            return _transports.find(name);
        };
        this.configure = function(configuration) {
            _configure.call(this, configuration);
        };
        this.init = function(configuration, handshakeProps) {
            this.configure(configuration);
            this.handshake(handshakeProps);
        };
        this.handshake = function(handshakeProps, handshakeCallback) {
            _setStatus('disconnected');
            _reestablish = false;
            _handshake(handshakeProps, handshakeCallback);
        };
        this.disconnect = function(sync, disconnectProps, disconnectCallback) {
            if (_isDisconnected()) {
                return;
            }
            if (typeof sync !== 'boolean') {
                disconnectCallback = disconnectProps;
                disconnectProps = sync;
                sync = false;
            }
            if (_isFunction(disconnectProps)) {
                disconnectCallback = disconnectProps;
                disconnectProps = undefined;
            }
            var bayeuxMessage = {
                channel: '/meta/disconnect',
                _callback: disconnectCallback
            };
            var message = this._mixin(false, {}, disconnectProps, bayeuxMessage);
            _setStatus('disconnecting');
            _send(sync === true, [message], false, 'disconnect');
        };
        this.startBatch = function() {
            _startBatch();
        };
        this.endBatch = function() {
            _endBatch();
        };
        this.batch = function(scope, callback) {
            var delegate = _resolveScopedCallback(scope, callback);
            this.startBatch();
            try {
                delegate.method.call(delegate.scope);
                this.endBatch();
            } catch (x) {
                this._info('Exception during execution of batch', x);
                this.endBatch();
                throw x;
            }
        };
        this.addListener = function(channel, scope, callback) {
            if (arguments.length < 2) {
                throw 'Illegal arguments number: required 2, got ' + arguments.length;
            }
            if (!_isString(channel)) {
                throw 'Illegal argument type: channel must be a string';
            }
            return _addListener(channel, scope, callback, true);
        };
        this.removeListener = function(subscription) {
            if (!subscription || !subscription.channel || !("id" in subscription)) {
                throw 'Invalid argument: expected subscription, not ' + subscription;
            }
            _removeListener(subscription);
        };
        this.clearListeners = function() {
            _listeners = {};
        };
        this.subscribe = function(channel, scope, callback, subscribeProps, subscribeCallback) {
            if (arguments.length < 2) {
                throw 'Illegal arguments number: required 2, got ' + arguments.length;
            }
            if (!_isString(channel)) {
                throw 'Illegal argument type: channel must be a string';
            }
            if (_isDisconnected()) {
                throw 'Illegal state: already disconnected';
            }
            if (_isFunction(scope)) {
                subscribeCallback = subscribeProps;
                subscribeProps = callback;
                callback = scope;
                scope = undefined;
            }
            if (_isFunction(subscribeProps)) {
                subscribeCallback = subscribeProps;
                subscribeProps = undefined;
            }
            var send = !_hasSubscriptions(channel);
            var subscription = _addListener(channel, scope, callback, false);
            if (send) {
                var bayeuxMessage = {
                    channel: '/meta/subscribe',
                    subscription: channel,
                    _callback: subscribeCallback
                };
                var message = this._mixin(false, {}, subscribeProps, bayeuxMessage);
                _queueSend(message);
            }
            return subscription;
        };
        this.unsubscribe = function(subscription, unsubscribeProps, unsubscribeCallback) {
            if (arguments.length < 1) {
                throw 'Illegal arguments number: required 1, got ' + arguments.length;
            }
            if (_isDisconnected()) {
                throw 'Illegal state: already disconnected';
            }
            if (_isFunction(unsubscribeProps)) {
                unsubscribeCallback = unsubscribeProps;
                unsubscribeProps = undefined;
            }
            this.removeListener(subscription);
            var channel = subscription.channel;
            if (!_hasSubscriptions(channel)) {
                var bayeuxMessage = {
                    channel: '/meta/unsubscribe',
                    subscription: channel,
                    _callback: unsubscribeCallback
                };
                var message = this._mixin(false, {}, unsubscribeProps, bayeuxMessage);
                _queueSend(message);
            }
        };
        this.resubscribe = function(subscription, subscribeProps) {
            _removeSubscription(subscription);
            if (subscription) {
                return this.subscribe(subscription.channel, subscription.scope, subscription.callback, subscribeProps);
            }
            return undefined;
        };
        this.clearSubscriptions = function() {
            _clearSubscriptions();
        };
        this.publish = function(channel, content, publishProps, publishCallback) {
            if (arguments.length < 1) {
                throw 'Illegal arguments number: required 1, got ' + arguments.length;
            }
            if (!_isString(channel)) {
                throw 'Illegal argument type: channel must be a string';
            }
            if (/^\/meta\//.test(channel)) {
                throw 'Illegal argument: cannot publish to meta channels';
            }
            if (_isDisconnected()) {
                throw 'Illegal state: already disconnected';
            }
            if (_isFunction(content)) {
                publishCallback = content;
                content = publishProps = {};
            } else if (_isFunction(publishProps)) {
                publishCallback = publishProps;
                publishProps = {};
            }
            var bayeuxMessage = {
                channel: channel,
                data: content,
                _callback: publishCallback
            };
            var message = this._mixin(false, {}, publishProps, bayeuxMessage);
            _queueSend(message);
        };
        this.getStatus = function() {
            return _status;
        };
        this.isDisconnected = _isDisconnected;
        this.setBackoffIncrement = function(period) {
            _config.backoffIncrement = period;
        };
        this.getBackoffIncrement = function() {
            return _config.backoffIncrement;
        };
        this.getBackoffPeriod = function() {
            return _backoff;
        };
        this.setLogLevel = function(level) {
            _config.logLevel = level;
        };
        this.registerExtension = function(name, extension) {
            if (arguments.length < 2) {
                throw 'Illegal arguments number: required 2, got ' + arguments.length;
            }
            if (!_isString(name)) {
                throw 'Illegal argument type: extension name must be a string';
            }
            var existing = false;
            for (var i = 0; i < _extensions.length; ++i) {
                var existingExtension = _extensions[i];
                if (existingExtension.name === name) {
                    existing = true;
                    break;
                }
            }
            if (!existing) {
                _extensions.push({
                    name: name,
                    extension: extension
                });
                this._debug('Registered extension', name);
                if (_isFunction(extension.registered)) {
                    extension.registered(name, this);
                }
                return true;
            } else {
                this._info('Could not register extension with name', name, 'since another extension with the same name already exists');
                return false;
            }
        };
        this.unregisterExtension = function(name) {
            if (!_isString(name)) {
                throw 'Illegal argument type: extension name must be a string';
            }
            var unregistered = false;
            for (var i = 0; i < _extensions.length; ++i) {
                var extension = _extensions[i];
                if (extension.name === name) {
                    _extensions.splice(i, 1);
                    unregistered = true;
                    this._debug('Unregistered extension', name);
                    var ext = extension.extension;
                    if (_isFunction(ext.unregistered)) {
                        ext.unregistered();
                    }
                    break;
                }
            }
            return unregistered;
        };
        this.getExtension = function(name) {
            for (var i = 0; i < _extensions.length; ++i) {
                var extension = _extensions[i];
                if (extension.name === name) {
                    return extension.extension;
                }
            }
            return null;
        };
        this.getName = function() {
            return _name;
        };
        this.getClientId = function() {
            return _clientId;
        };
        this.getURL = function() {
            if (_transport && typeof _config.urls === 'object') {
                var url = _config.urls[_transport.getType()];
                if (url) {
                    return url;
                }
            }
            return _config.url;
        };
        this.getTransport = function() {
            return _transport;
        };
        this.getConfiguration = function() {
            return this._mixin(true, {}, _config);
        };
        this.getAdvice = function() {
            return this._mixin(true, {}, _advice);
        };
        org.cometd.WebSocket = window.WebSocket;
        if (!org.cometd.WebSocket) {
            org.cometd.WebSocket = window.MozWebSocket;
        }
    };
    if (typeof define === 'function' && define.amd) {
        define(function() {
            return org.cometd;
        });
    };
    /*! RESOURCE: /scripts/thirdparty/cometd/jquery/jquery.cometd.js */
    (function() {
        function bind($, org_cometd) {
            org_cometd.JSON.toJSON = (window.JSON && JSON.stringify) || (window.jaredJSON && window.jaredJSON.stringify);
            org_cometd.JSON.fromJSON = (window.JSON && JSON.parse) || (window.jaredJSON && window.jaredJSON.parse);
    
            function _setHeaders(xhr, headers) {
                if (headers) {
                    for (var headerName in headers) {
                        if (headerName.toLowerCase() === 'content-type') {
                            continue;
                        }
                        xhr.setRequestHeader(headerName, headers[headerName]);
                    }
                }
            }
    
            function LongPollingTransport() {
                var _super = new org_cometd.LongPollingTransport();
                var that = org_cometd.Transport.derive(_super);
                that.xhrSend = function(packet) {
                    return $.ajax({
                        url: packet.url,
                        async: packet.sync !== true,
                        type: 'POST',
                        contentType: 'application/json;charset=UTF-8',
                        data: packet.body,
                        xhrFields: {
                            withCredentials: true
                        },
                        beforeSend: function(xhr) {
                            _setHeaders(xhr, packet.headers);
                            return true;
                        },
                        success: packet.onSuccess,
                        error: function(xhr, reason, exception) {
                            packet.onError(reason, exception);
                        }
                    });
                };
                return that;
            }
    
            function CallbackPollingTransport() {
                var _super = new org_cometd.CallbackPollingTransport();
                var that = org_cometd.Transport.derive(_super);
                that.jsonpSend = function(packet) {
                    $.ajax({
                        url: packet.url,
                        async: packet.sync !== true,
                        type: 'GET',
                        dataType: 'jsonp',
                        jsonp: 'jsonp',
                        data: {
                            message: packet.body
                        },
                        beforeSend: function(xhr) {
                            _setHeaders(xhr, packet.headers);
                            return true;
                        },
                        success: packet.onSuccess,
                        error: function(xhr, reason, exception) {
                            packet.onError(reason, exception);
                        }
                    });
                };
                return that;
            }
            $.Cometd = function(name) {
                var cometd = new org_cometd.Cometd(name);
                if (org_cometd.WebSocket) {
                    cometd.registerTransport('websocket', new org_cometd.WebSocketTransport());
                }
                cometd.registerTransport('long-polling', new LongPollingTransport());
                cometd.registerTransport('callback-polling', new CallbackPollingTransport());
                return cometd;
            };
            $.cometd = new $.Cometd();
            return $.cometd;
        }
        if (typeof define === 'function' && define.amd) {
            define(['jquery', 'org/cometd'], bind);
        } else {
            bind(window.jQuery1110 || window.Zepto, org.cometd);
        }
    })();;
    /*! RESOURCE: /scripts/amb_properties.js */
    var amb = amb || {
        properties: {
            servletURI: 'amb/',
            logLevel: 'info',
            loginWindow: 'true'
        }
    };;
    /*! RESOURCE: /scripts/amb.Logger.js */
    amb['Logger'] = function(callerType) {
        var _debugEnabled = amb['properties']['logLevel'] == 'debug';
    
        function print(message) {
            console.log(callerType + ' ' + message);
        }
        return {
            debug: function(message) {
                if (_debugEnabled)
                    print('[DEBUG] ' + message);
            },
            addInfoMessage: function(message) {
                print('[INFO] ' + message);
            },
            addErrorMessage: function(message) {
                print('[ERROR] ' + message);
            }
        }
    };;
    /*! RESOURCE: /scripts/amb.EventManager.js */
    amb.EventManager = function EventManager(events) {
        var _subscriptions = [];
        var _idCounter = 0;
    
        function _getSubscriptions(event) {
            var subscriptions = [];
            for (var i = 0; i < _subscriptions.length; i++) {
                if (_subscriptions[i].event == event)
                    subscriptions.push(_subscriptions[i]);
            }
            return subscriptions;
        }
        return {
            subscribe: function(event, callback) {
                var id = _idCounter++;
                _subscriptions.push({
                    event: event,
                    callback: callback,
                    id: id
                });
                return id;
            },
            unsubscribe: function(id) {
                for (var i = 0; i < _subscriptions.length; i++)
                    if (id == _subscriptions[i].id)
                        _subscriptions.splice(i, 1);
            },
            publish: function(event, args) {
                var subscriptions = _getSubscriptions(event);
                for (var i = 0; i < subscriptions.length; i++)
                    subscriptions[i].callback.apply(null, args);
            },
            getEvents: function() {
                return events;
            }
        }
    };;
    /*! RESOURCE: /scripts/amb.ServerConnection.js */
    amb.ServerConnection = function ServerConnection(cometd) {
        var connected = false;
        var disconnecting = false;
        var eventManager = new amb.EventManager({
            CONNECTION_INITIALIZED: 'connection.initialized',
            CONNECTION_OPENED: 'connection.opened',
            CONNECTION_CLOSED: 'connection.closed',
            CONNECTION_BROKEN: 'connection.broken',
            SESSION_LOGGED_IN: 'session.logged.in',
            SESSION_LOGGED_OUT: 'session.logged.out'
        });
        var state = "closed";
        var LOGGER = new amb.Logger('amb.ServerConnection');
        _initializeMetaChannelListeners();
        var loggedIn = true;
        var loginWindow = null;
        var loginWindowEnabled = amb.properties['loginWindow'] === 'true';
        var lastError = null;
        var errorMessages = {
            'UNKNOWN_CLIENT': '402::Unknown client'
        };
        var loginWindowOverride = false;
        var ambServerConnection = {};
        ambServerConnection.connect = function() {
            if (connected) {
                console.log(">>> connection exists, request satisfied");
                return;
            }
            LOGGER.debug('Connecting to glide amb server -> ' + amb['properties']['servletURI']);
            LOGGER.debug('Connecting to glide amb server -> ' + amb['properties']['servletURI']);
            cometd.configure({
                url: _getRelativePath(amb['properties']['servletURI']),
                logLevel: amb['properties']['logLevel']
            });
            cometd.handshake();
        };
        ambServerConnection.reload = function() {
            cometd.reload();
        };
        ambServerConnection.abort = function() {
            cometd.getTransport().abort();
        };
        ambServerConnection.disconnect = function() {
            LOGGER.debug('Disconnecting from glide amb server..');
            disconnecting = true;
            cometd.disconnect();
        };
    
        function _initializeMetaChannelListeners() {
            cometd.addListener('/meta/handshake', this, _metaHandshake);
            cometd.addListener('/meta/connect', this, _metaConnect);
        }
    
        function _metaHandshake(message) {
            setTimeout(function() {
                if (message['successful'])
                    _connectionInitialized();
            }, 0);
        }
    
        function _metaConnect(message) {
            if (disconnecting) {
                setTimeout(function() {
                    connected = false;
                    _connectionClosed();
                }, 0);
                return;
            }
            var error = message['error'];
            if (error)
                lastError = error;
            _sessionStatus(message);
            var wasConnected = connected;
            connected = (message['successful'] === true);
            if (!wasConnected && connected)
                _connectionOpened();
            else if (wasConnected && !connected)
                _connectionBroken();
        }
    
        function _connectionInitialized() {
            LOGGER.debug('Connection initialized');
            state = "initialized";
            eventManager.publish(eventManager.getEvents().CONNECTION_INITIALIZED);
        }
    
        function _connectionOpened() {
            LOGGER.debug('Connection opened');
            state = "opened";
            eventManager.publish(eventManager.getEvents().CONNECTION_OPENED);
        }
    
        function _connectionClosed() {
            LOGGER.debug('Connection closed');
            state = "closed";
            eventManager.publish(eventManager.getEvents().CONNECTION_CLOSED);
        }
    
        function _connectionBroken() {
            LOGGER.addErrorMessage('Connection broken');
            state = "broken";
            eventManager.publish(eventManager.getEvents().CONNECTION_BROKEN);
        }
    
        function _sessionStatus(message) {
            var ext = message['ext'];
            if (ext) {
                var sessionStatus = ext['glide.session.status'];
                loginWindowOverride = ext['glide.amb.login.window.override'] === true;
                LOGGER.debug('session.status - ' + sessionStatus);
                switch (sessionStatus) {
                    case 'session.logged.out':
                        if (loggedIn)
                            _logout();
                        break;
                    case 'session.logged.in':
                        if (!loggedIn)
                            _login();
                        break;
                    default:
                        LOGGER.debug("unknown session status - " + sessionStatus);
                        break;
                }
            }
        }
    
        function _login() {
            loggedIn = true;
            LOGGER.debug("LOGGED_IN event fire!");
            eventManager.publish(eventManager.getEvents().SESSION_LOGGED_IN);
            ambServerConnection.loginHide();
        }
    
        function _logout() {
            loggedIn = false;
            LOGGER.debug("LOGGED_OUT event fire!");
            eventManager.publish(eventManager.getEvents().SESSION_LOGGED_OUT);
            ambServerConnection.loginShow();
        }
        var modalContent = '<iframe src="/amb_login.do" frameborder="0" height="400px" width="405px" scrolling="no"></iframe>';
        var modalTemplate = '<div id="amb_disconnect_modal" tabindex="-1" aria-hidden="true" class="modal" role="dialog">' +
            '  <div class="modal-dialog small-modal" style="width:450px">' +
            '     <div class="modal-content">' +
            '        <header class="modal-header">' +
            '           <h4 id="small_modal1_title" class="modal-title">Login</h4>' +
            '        </header>' +
            '        <div class="modal-body">' +
            '        </div>' +
            '     </div>' +
            '  </div>' +
            '</div>';
    
        function _loginShow() {
            if (!loginWindowEnabled || loginWindowOverride)
                return;
            var dialog = new GlideModal('amb_disconnect_modal');
            if (dialog['renderWithContent']) {
                dialog.template = modalTemplate;
                dialog.renderWithContent(modalContent);
            } else {
                dialog.setBody(modalContent);
                dialog.render();
            }
            loginWindow = dialog;
        }
    
        function _loginHide() {
            if (!loginWindow)
                return;
            loginWindow.destroy();
            loginWindow = null;
        }
    
        function loginComplete() {
            _login();
        }
    
        function _getRelativePath(uri) {
            var relativePath = "";
            for (var i = 0; i < window.location.pathname.match(/\//g).length - 1; i++) {
                relativePath = "../" + relativePath;
            }
            return relativePath + uri;
        }
        ambServerConnection.loginShow = function() {
            _loginShow();
        };
        ambServerConnection.loginHide = function() {
            _loginHide();
        };
        ambServerConnection.getEvents = function() {
            return eventManager.getEvents();
        };
        ambServerConnection.getConnectionState = function() {
            return state;
        };
        ambServerConnection.getLastError = function() {
            return lastError;
        };
        ambServerConnection.setLastError = function(error) {
            lastError = error;
        };
        ambServerConnection.getErrorMessages = function() {
            return errorMessages;
        };
        ambServerConnection.isLoggedIn = function() {
            return loggedIn;
        };
        ambServerConnection.loginShow = function() {
            _loginShow();
        };
        ambServerConnection.loginHide = function() {
            _loginHide();
        };
        ambServerConnection.loginComplete = function() {
            _login();
        };
        ambServerConnection.getEvents = function() {
            return eventManager.getEvents();
        };
        ambServerConnection.subscribeToEvent = function(event, callback) {
            if (eventManager.getEvents().CONNECTION_OPENED == event && connected)
                callback();
            return eventManager.subscribe(event, callback);
        };
        ambServerConnection.unsubscribeFromEvent = function(id) {
            eventManager.unsubscribe(id);
        };
        ambServerConnection.getConnectionState = function() {
            return state;
        };
        ambServerConnection.isLoggedIn = function() {
            return loggedIn;
        };
        ambServerConnection.loginShow = function() {
            _loginShow();
        };
        ambServerConnection.loginHide = function() {
            _loginHide();
        };
        ambServerConnection.loginComplete = function() {
            _login();
        };
        ambServerConnection.isLoginWindowEnabled = function() {
            return loginWindowEnabled;
        };
        ambServerConnection.isLoginWindowOverride = function() {
            return loginWindowOverride;
        }
        return ambServerConnection;
    };;
    /*! RESOURCE: /scripts/amb.ChannelRedirect.js */
    amb.ChannelRedirect = function ChannelRedirect(cometd, serverConnection,
        channelProvider) {
        var initialized = false;
        var _cometd = cometd;
        var eventManager = new amb.EventManager({
            CHANNEL_REDIRECT: 'channel.redirect'
        });
        var LOGGER = new amb.Logger('amb.ChannelRedirect');
    
        function _onAdvice(advice) {
            LOGGER.debug('_onAdvice:' + advice.data.clientId);
            var fromChannel = channelProvider(advice.data.fromChannel);
            var toChannel = channelProvider(advice.data.toChannel);
            eventManager.publish(eventManager.getEvents().CHANNEL_REDIRECT, [fromChannel, toChannel]);
            LOGGER.debug(
                'published channel switch event, fromChannel:' + fromChannel.getName() +
                ', toChannel:' + toChannel.getName());
        }
        return {
            subscribeToEvent: function(event, callback) {
                return eventManager.subscribe(event, callback);
            },
            unsubscribeToEvent: function(id) {
                eventManager.unsubscribe(id);
            },
            getEvents: function() {
                return eventManager.getEvents();
            },
            initialize: function() {
                if (!initialized) {
                    var channelName = '/sn/meta/channel_redirect/' + _cometd.getClientId();
                    var metaChannel = channelProvider(channelName);
                    metaChannel.newListener(serverConnection, null).subscribe(_onAdvice);
                    LOGGER.debug("ChannelRedirect initialized: " + channelName);
                    initialized = true;
                }
            }
        }
    };;
    /*! RESOURCE: /scripts/amb.ChannelListener.js */
    amb.ChannelListener = function ChannelListener(channel, serverConnection,
        channelRedirect) {
        var id;
        var subscriberCallback;
        var LOGGER = new amb.Logger('amb.ChannelListener');
        var channelRedirectId = null;
        var connectOpenedEventId;
        var currentChannel = channel;
        return {
            getCallback: function() {
                return subscriberCallback;
            },
            getID: function() {
                return id;
            },
            subscribe: function(callback) {
                subscriberCallback = callback;
                if (channelRedirect)
                    channelRedirectId = channelRedirect.subscribeToEvent(
                        channelRedirect.getEvents().CHANNEL_REDIRECT, this._switchToChannel.bind(this));
                connectOpenedEventId = serverConnection.subscribeToEvent(serverConnection.getEvents().CONNECTION_OPENED,
                    this._subscribeWhenReady.bind(this));
                LOGGER.debug("Subscribed from channel: " + currentChannel.getName());
                return this;
            },
            resubscribe: function() {
                return this.subscribe(subscriberCallback);
            },
            _switchToChannel: function(fromChannel, toChannel) {
                if (!fromChannel || !toChannel)
                    return;
                if (fromChannel.getName() != currentChannel.getName())
                    return;
                this.unsubscribe();
                currentChannel = toChannel;
                this.subscribe(subscriberCallback);
            },
            _subscribeWhenReady: function() {
                LOGGER.debug("Subscribing to '" + currentChannel.getName() + "'...");
                id = currentChannel.subscribe(this);
            },
            unsubscribe: function() {
                channelRedirect.unsubscribeToEvent(channelRedirectId);
                currentChannel.unsubscribe(this);
                serverConnection.unsubscribeFromEvent(connectOpenedEventId);
                LOGGER.debug("Unsubscribed from channel: " + currentChannel.getName());
                return this;
            },
            publish: function(message) {
                currentChannel.publish(message);
            },
            getName: function() {
                return currentChannel.getName();
            }
        }
    };;
    /*! RESOURCE: /scripts/amb.Channel.js */
    amb.Channel = function Channel(cometd, channelName, initialized) {
        var subscription = null;
        var listeners = [];
        var LOGGER = new amb.Logger('amb.Channel');
        var idCounter = 0;
        var _initialized = initialized;
    
        function _disconnected() {
            var status = cometd.getStatus();
            return status === 'disconnecting' || status === 'disconnected';
        }
        return {
            newListener: function(serverConnection,
                channelRedirect) {
                return new amb.ChannelListener(this, serverConnection, channelRedirect);
            },
            subscribe: function(listener) {
                if (!listener.getCallback()) {
                    LOGGER.addErrorMessage('Cannot subscribe to channel: ' + channelName +
                        ', callback not provided');
                    return;
                }
                if (!subscription && _initialized) {
                    subscription = cometd.subscribe(channelName, this._handleResponse.bind(this));
                    LOGGER.debug('Successfully subscribed to channel: ' + channelName);
                }
                for (var i = 0; i < listeners.length; i++) {
                    if (listeners[i] === listener) {
                        LOGGER.debug('Channel listener already in the list');
                        return listener.getID();
                    }
                }
                var id = idCounter++;
                listeners.push(listener);
                return id;
            },
            subscribeOnInitCompletion: function(redirect) {
                _initialized = true;
                subscription = null;
                for (var i = 0; i < listeners.length; i++) {
                    listeners[i].subscribe();
                    LOGGER.debug('Successfully subscribed to channel: ' + channelName);
                }
            },
            resubscribe: function() {
                subscription = null;
                for (var i = 0; i < listeners.length; i++)
                    listeners[i].resubscribe();
            },
            _handleResponse: function(message) {
                for (var i = 0; i < listeners.length; i++)
                    listeners[i].getCallback()(message);
            },
            unsubscribe: function(listener) {
                if (!listener) {
                    LOGGER.addErrorMessage('Cannot unsubscribe from channel: ' + channelName +
                        ', listener argument does not exist');
                    return;
                }
                for (var i = 0; i < listeners.length; i++) {
                    if (listeners[i].getID() == listener.getID())
                        listeners.splice(i, 1);
                }
                if (listeners.length < 1 && subscription && !_disconnected()) {
                    cometd.unsubscribe(subscription);
                    subscription = null;
                }
                LOGGER.debug('Successfully unsubscribed from channel: ' + channelName);
            },
            publish: function(message) {
                cometd.publish(channelName, message);
            },
            getName: function() {
                return channelName;
            }
        }
    };;
    /*! RESOURCE: /scripts/amb.MessageClient.js */
    (function($) {
        amb.MessageClient = function MessageClient() {
            var cometd = new $.Cometd();
            cometd.unregisterTransport('websocket');
            cometd.unregisterTransport('callback-polling');
            var serverConnection = new amb.ServerConnection(cometd);
            var channels = {};
            var LOGGER = new amb.Logger('amb.MessageClient');
            var channelRedirect = null;
            var connected = false;
            var initialized = false;
            var uninitializedChannels = [];
            serverConnection.subscribeToEvent(serverConnection.getEvents().CONNECTION_BROKEN, _connectionBroken);
            serverConnection.subscribeToEvent(serverConnection.getEvents().CONNECTION_OPENED, _connectionOpened);
            serverConnection.subscribeToEvent(serverConnection.getEvents().CONNECTION_INITIALIZED, _connectionInitialized);
            var _connectionBrokenEvent = false;
    
            function _connectionBroken() {
                LOGGER.debug("connection broken!");
                _connectionBrokenEvent = true;
            }
    
            function _connectionInitialized() {
                initialized = true;
                _initChannelRedirect();
                channelRedirect.initialize();
                LOGGER.debug("Connection initialized. Initializing " + uninitializedChannels.length + " channels.");
                for (var i = 0; i < uninitializedChannels.length; i++) {
                    uninitializedChannels[i].subscribeOnInitCompletion();
                }
                uninitializedChannels = [];
            }
    
            function _connectionOpened() {
                if (_connectionBrokenEvent) {
                    LOGGER.debug("connection opened!");
                    _connectionBrokenEvent = false;
                    var sc = serverConnection;
                    if (sc.getLastError() !== sc.getErrorMessages().UNKNOWN_CLIENT)
                        return;
                    sc.setLastError(null);
                    LOGGER.debug("channel resubscribe!");
                    $.ajax({
                        url: "/amb_session_setup.do",
                        method: "GET",
                        contentType: "application/json;charset=UTF-8",
                        data: "",
                        dataType: "HTML",
                        headers: {
                            'X-UserToken': window.g_ck
                        }
                    }).done(function() {
                        for (var name in channels) {
                            var channel = channels[name];
                            channel.resubscribe();
                        }
                    });
                }
            }
    
            function _initChannelRedirect() {
                if (channelRedirect)
                    return;
                channelRedirect = new amb.ChannelRedirect(cometd, serverConnection, _getChannel);
            }
    
            function _getChannel(channelName) {
                if (channelName in channels)
                    return channels[channelName];
                var channel = new amb.Channel(cometd, channelName, initialized);
                channels[channelName] = channel;
                if (!initialized)
                    uninitializedChannels.push(channel);
                return channel;
            }
            return {
                getServerConnection: function() {
                    return serverConnection;
                },
                isLoggedIn: function() {
                    return serverConnection.isLoggedIn();
                },
                loginComplete: function() {
                    serverConnection.loginComplete();
                },
                connect: function() {
                    if (connected) {
                        LOGGER.addInfoMessage(">>> connection exists, request satisfied");
                        return;
                    }
                    connected = true;
                    serverConnection.connect();
                },
                reload: function() {
                    connected = false;
                    serverConnection.reload();
                },
                abort: function() {
                    connected = false;
                    serverConnection.abort();
                },
                disconnect: function() {
                    connected = false;
                    serverConnection.disconnect();
                },
                getConnectionEvents: function() {
                    return serverConnection.getEvents();
                },
                subscribeToEvent: function(event, callback) {
                    return serverConnection.subscribeToEvent(event, callback);
                },
                unsubscribeFromEvent: function(id) {
                    serverConnection.unsubscribeFromEvent(id);
                },
                getConnectionState: function() {
                    return serverConnection.getConnectionState();
                },
                getClientId: function() {
                    return cometd.getClientId();
                },
                getChannel: function(channelName) {
                    _initChannelRedirect();
                    var channel = _getChannel(channelName);
                    return channel.newListener(serverConnection, channelRedirect);
                },
                registerExtension: function(extensionName, extension) {
                    cometd.registerExtension(extensionName, extension);
                },
                unregisterExtension: function(extensionName) {
                    cometd.unregisterExtension(extensionName);
                },
                batch: function(block) {
                    cometd.batch(block);
                }
            }
        };
    })(jQuery1110);;
    /*! RESOURCE: /scripts/amb.MessageClientBuilder.js */
    (function($) {
        amb.getClient = function() {
            return getClient();
        }
    
        function getClient() {
            var _window = window.self;
            try {
                if (!(window.MSInputMethodContext && document.documentMode)) {
                    while (_window != _window.parent) {
                        if (_window.g_ambClient)
                            break;
                        _window = _window.parent;
                    }
                }
                if (_window.g_ambClient)
                    return _window.g_ambClient;
            } catch (e) {
                console.log("AMB getClient() tried to access parent from an iFrame. Caught error: " + e);
            }
            var client = buildClient();
            setClient(client);
            return client;
        }
    
        function setClient(client) {
            var _window = window.self;
            _window.g_ambClient = client;
            $(_window).unload(function() {
                _window.g_ambClient.disconnect();
            });
            _window.g_ambClient.connect();
        }
    
        function buildClient() {
            return (function() {
                var ambClient = new amb.MessageClient();
                return {
                    getServerConnection: function() {
                        return ambClient.getServerConnection();
                    },
                    connect: function() {
                        ambClient.connect();
                    },
                    abort: function() {
                        ambClient.abort();
                    },
                    disconnect: function() {
                        ambClient.disconnect();
                    },
                    getConnectionState: function() {
                        return ambClient.getConnectionState();
                    },
                    getState: function() {
                        return ambClient.getConnectionState();
                    },
                    getClientId: function() {
                        return ambClient.getClientId();
                    },
                    getChannel: function(channelName) {
                        var channel = ambClient.getChannel(channelName);
                        var originalSubscribe = channel.subscribe;
                        var originalUnsubscribe = channel.unsubscribe;
                        channel.subscribe = function(listener) {
                            originalSubscribe.call(channel, listener);
                            $(window).unload(function(event) {
                                originalUnsubscribe.call(channel);
                            });
                            return channel;
                        };
                        return channel;
                    },
                    getChannel0: function(channelName) {
                        return ambClient.getChannel(channelName);
                    },
                    registerExtension: function(extensionName, extension) {
                        ambClient.registerExtension(extensionName, extension);
                    },
                    unregisterExtension: function(extensionName) {
                        ambClient.unregisterExtension(extensionName);
                    },
                    batch: function(block) {
                        ambClient.batch(block);
                    },
                    subscribeToEvent: function(event, callback) {
                        return ambClient.subscribeToEvent(event, callback);
                    },
                    unsubscribeFromEvent: function(id) {
                        ambClient.unsubscribeFromEvent(id);
                    },
                    isLoggedIn: function() {
                        return ambClient.isLoggedIn();
                    },
                    getConnectionEvents: function() {
                        return ambClient.getConnectionEvents();
                    },
                    getEvents: function() {
                        return ambClient.getConnectionEvents();
                    },
                    loginComplete: function() {
                        ambClient.loginComplete();
                    }
                };
            })();
        }
    })(jQuery1110);;
    /*! RESOURCE: /scripts/amb_initialize.js */
    if (typeof g_amb_on_login === 'undefined') {
        amb.getClient();
    };;
    /*! RESOURCE: /scripts/app.ng.amb/app.ng.amb.js */
    angular.module("ng.amb", ['sn.common.presence', 'sn.common.util'])
        .value("ambLogLevel", 'info')
        .value("ambServletURI", '/amb')
        .value("cometd", angular.element.cometd)
        .value("ambLoginWindow", 'true');;
    /*! RESOURCE: /scripts/app.ng.amb/service.AMB.js */
    angular.module("ng.amb").service("amb", function(AMBOverlay, $window, $q, $log, $rootScope, $timeout) {
        "use strict";
        var ambClient = null;
        var _window = $window.self;
        var loginWindow = null;
        var sameScope = false;
        if (_window.g_ambClient) {
            ambClient = _window.g_ambClient;
            sameScope = true;
        }
        if (!ambClient)
            ambClient = amb.getClient();
        if (sameScope) {
            var serverConnection = ambClient.getServerConnection();
            serverConnection.loginShow = function() {
                if (!serverConnection.isLoginWindowEnabled())
                    return;
                if (loginWindow && loginWindow.isVisible())
                    return;
                if (serverConnection.isLoginWindowOverride())
                    return;
                loginWindow = new AMBOverlay();
                loginWindow.render();
                loginWindow.show();
            };
            serverConnection.loginHide = function() {
                if (!loginWindow)
                    return;
                loginWindow.hide();
                loginWindow.destroy();
                loginWindow = null;
            }
        }
        var connected = $q.defer();
        var connectionInterrupted = false;
        var monitorAMB = false;
        $timeout(function() {
            monitorAMB = true;
        }, 5 * 1000);
    
        function ambInterrupted() {
            var state = ambClient.getState();
            return monitorAMB && state !== "opened" && state !== "initialized"
        }
        var interruptionTimeout;
        var extendedInterruption = false;
    
        function setInterrupted(eventName) {
            connectionInterrupted = true;
            $rootScope.$broadcast(eventName);
            if (!interruptionTimeout) {
                interruptionTimeout = $timeout(function() {
                    extendedInterruption = true;
                }, 30 * 1000)
            }
            connected = $q.defer();
        }
        var connectOpenedEventId = ambClient.subscribeToEvent("connection.opened", function() {
            $rootScope.$broadcast("amb.connection.opened");
            if (interruptionTimeout) {
                $timeout.cancel(interruptionTimeout);
                interruptionTimeout = null;
            }
            extendedInterruption = false;
            if (connectionInterrupted) {
                connectionInterrupted = false;
                $rootScope.$broadcast("amb.connection.recovered");
            }
            connected.resolve();
        });
        var connectClosedEventId = ambClient.subscribeToEvent("connection.closed", function() {
            setInterrupted("amb.connection.closed");
        });
        var connectBrokenEventId = ambClient.subscribeToEvent("connection.broken", function() {
            setInterrupted("amb.connection.broken");
        });
        jQuery(window).unload(function fixMemoryLeakInGlobalAMBEventManager(event) {
            ambClient.unsubscribeFromEvent(connectOpenedEventId);
            ambClient.unsubscribeFromEvent(connectClosedEventId);
            ambClient.unsubscribeFromEvent(connectBrokenEventId);
            jQuery(this).unbind(event);
        });
        ambClient.connect();
        return {
            getServerConnection: function() {
                return ambClient.getServerConnection();
            },
            connect: function() {
                ambClient.connect();
                return connected.promise;
            },
            get interrupted() {
                return ambInterrupted();
            },
            get extendedInterruption() {
                return extendedInterruption;
            },
            get connected() {
                return connected.promise;
            },
            abort: function() {
                ambClient.abort();
            },
            disconnect: function() {
                ambClient.disconnect();
            },
            getConnectionState: function() {
                return ambClient.getConnectionState();
            },
            getClientId: function() {
                return ambClient.getClientId();
            },
            getChannel: function(channelName) {
                var channel = ambClient.getChannel0(channelName);
                var originalSubscribe = channel.subscribe;
                var originalUnsubscribe = channel.unsubscribe;
                channel.subscribe = function(listener) {
                    originalSubscribe.call(channel, listener);
                    jQuery(window).unload(function() {
                        originalUnsubscribe.call(channel);
                    });
                    return channel;
                };
                return channel;
            },
            registerExtension: function(extensionName, extension) {
                ambClient.registerExtension(extensionName, extension);
            },
            unregisterExtension: function(extensionName) {
                ambClient.unregisterExtension(extensionName);
            },
            batch: function(batch) {
                ambClient.batch(batch);
            },
            getState: function() {
                return ambClient.getState();
            },
            getFilterString: function(filter) {
                filter = filter.
                replace(/\^EQ/g, '').
                replace(/\^ORDERBY(?:DESC)?[^^]*/g, '').
                replace(/^GOTO/, '');
                return btoa(filter).replace(/=/g, '-');
            },
            getChannelRW: function(table, filter) {
                var t = '/rw/default/' + table + '/' + this.getFilterString(filter);
                return this.getChannel(t);
            },
            isLoggedIn: function() {
                return ambClient.isLoggedIn();
            },
            subscribeToEvent: function(event, callback) {
                ambClient.subscribeToEvent(event, callback);
            },
            getConnectionEvents: function() {
                return ambClient.getConnectionEvents();
            },
            getEvents: function() {
                return ambClient.getConnectionEvents();
            },
            loginComplete: function() {
                ambClient.loginComplete();
            }
        };
    });;
    /*! RESOURCE: /scripts/app.ng.amb/controller.AMBRecordWatcher.js */
    angular.module("ng.amb").controller("AMBRecordWatcher", function($scope, $timeout, $window) {
        "use strict";
        var amb = $window.top.g_ambClient;
        $scope.messages = [];
        var lastFilter;
        var watcherChannel;
        var watcher;
    
        function onMessage(message) {
            $scope.messages.push(message.data);
        }
        $scope.getState = function() {
            return amb.getState();
        };
        $scope.initWatcher = function() {
            angular.element(":focus").blur();
            if (!$scope.filter || $scope.filter === lastFilter)
                return;
            lastFilter = $scope.filter;
            console.log("initiating watcher on " + $scope.filter);
            $scope.messages = [];
            if (watcher) {
                watcher.unsubscribe();
            }
            var base64EncodeQuery = btoa($scope.filter).replace(/=/g, '-');
            var channelId = '/rw/' + base64EncodeQuery;
            watcherChannel = amb.getChannel(channelId)
            watcher = watcherChannel.subscribe(onMessage);
        };
        amb.connect();
    });
    /*! RESOURCE: /scripts/app.ng.amb/factory.snRecordWatcher.js */
    angular.module("ng.amb").factory('snRecordWatcher', function($rootScope, amb, $timeout, snPresence, $log, urlTools) {
        "use strict";
        var watcherChannel;
        var connected = false;
        var diagnosticLog = true;
    
        function initWatcher(table, sys_id, query) {
            if (!table)
                return;
            if (sys_id)
                var filter = "sys_id=" + sys_id;
            else
                filter = query;
            if (!filter)
                return;
            return initChannel(table, filter);
        }
    
        function initList(table, query) {
            if (!table)
                return;
            query = query || "sys_idISNOTEMPTY";
            return initChannel(table, query);
        }
    
        function initTaskList(list, prevChannel) {
            if (prevChannel)
                prevChannel.unsubscribe();
            var sys_ids = list.toString();
            var filter = "sys_idIN" + sys_ids;
            return initChannel("task", filter);
        }
    
        function initChannel(table, filter) {
            if (isBlockedTable(table)) {
                $log.log("Blocked from watching", table);
                return null;
            }
            if (diagnosticLog)
                log(">>> init " + table + "?" + filter);
            watcherChannel = amb.getChannelRW(table, filter);
            watcherChannel.subscribe(onMessage);
            amb.connect();
            return watcherChannel;
        }
    
        function onMessage(message) {
            var r = message.data;
            var c = message.channel;
            if (diagnosticLog)
                log(">>> record " + r.operation + ": " + r.table_name + "." + r.sys_id + " " + r.display_value);
            $rootScope.$broadcast('record.updated', r);
            $rootScope.$broadcast("sn.stream.tap");
            $rootScope.$broadcast('list.updated', r, c);
        }
    
        function log(message) {
            $log.log(message);
        }
    
        function isBlockedTable(table) {
            return table == 'sys_amb_message' || table.startsWith('sys_rw');
        }
        return {
            initTaskList: initTaskList,
            initChannel: initChannel,
            init: function() {
                var location = urlTools.parseQueryString(window.location.search);
                var table = location['table'] || location['sysparm_table'];
                var sys_id = location['sys_id'] || location['sysparm_sys_id'];
                var query = location['sysparm_query'];
                initWatcher(table, sys_id, query);
                snPresence.init(table, sys_id, query);
            },
            initList: initList,
            initRecord: function(table, sysId) {
                initWatcher(table, sysId, null);
                snPresence.initWithDocument(table, sysId);
            }
        }
    });;
    /*! RESOURCE: /scripts/app.ng.amb/factory.AMBOverlay.js */
    angular.module("ng.amb").factory("AMBOverlay", function($templateCache, $compile, $rootScope) {
        "use strict";
        var showCallbacks = [],
            hideCallbacks = [],
            isRendered = false,
            modal,
            modalScope,
            modalOptions;
        var defaults = {
            backdrop: 'static',
            keyboard: false,
            show: true
        };
    
        function AMBOverlay(config) {
            config = config || {};
            if (angular.isFunction(config.onShow))
                showCallbacks.push(config.onShow);
            if (angular.isFunction(config.onHide))
                hideCallbacks.push(config.onHide);
    
            function lazyRender() {
                if (!angular.element('html')['modal']) {
                    var bootstrapInclude = "/scripts/bootstrap3/bootstrap.js";
                    ScriptLoader.getScripts([bootstrapInclude], renderModal);
                } else
                    renderModal();
            }
    
            function renderModal() {
                if (isRendered)
                    return;
                modalScope = angular.extend($rootScope.$new(), config);
                modal = $compile($templateCache.get("amb_disconnect_modal.xml"))(modalScope);
                angular.element("body").append(modal);
                modal.on("shown.bs.modal", function(e) {
                    for (var i = 0, len = showCallbacks.length; i < len; i++)
                        showCallbacks[i](e);
                });
                modal.on("hidden.bs.modal", function(e) {
                    for (var i = 0, len = hideCallbacks.length; i < len; i++)
                        hideCallbacks[i](e);
                });
                modalOptions = angular.extend({}, defaults, config);
                modal.modal(modalOptions);
                isRendered = true;
            }
    
            function showModal() {
                if (isRendered)
                    modal.modal('show');
            }
    
            function hideModal() {
                if (isRendered)
                    modal.modal('hide');
            }
    
            function destroyModal() {
                if (!isRendered)
                    return;
                modal.modal('hide');
                modal.remove();
                modalScope.$destroy();
                modalScope = void(0);
                isRendered = false;
                var pos = showCallbacks.indexOf(config.onShow);
                if (pos >= 0)
                    showCallbacks.splice(pos, 1);
                pos = hideCallbacks.indexOf(config.onShow);
                if (pos >= 0)
                    hideCallbacks.splice(pos, 1);
            }
            return {
                render: lazyRender,
                destroy: destroyModal,
                show: showModal,
                hide: hideModal,
                isVisible: function() {
                    if (!isRendered)
                        false;
                    return modal.visible();
                }
            }
        }
        $templateCache.put('amb_disconnect_modal.xml',
            '<div id="amb_disconnect_modal" tabindex="-1" aria-hidden="true" class="modal" role="dialog">' +
            '	<div class="modal-dialog small-modal" style="width:450px">' +
            '		<div class="modal-content">' +
            '			<header class="modal-header">' +
            '				<h4 id="small_modal1_title" class="modal-title">{{title || "Login"}}</h4>' +
            '			</header>' +
            '			<div class="modal-body">' +
            '			<iframe class="concourse_modal" ng-src=\'{{iframe || "/amb_login.do"}}\' frameborder="0" scrolling="no" height="400px" width="405px"></iframe>' +
            '			</div>' +
            '		</div>' +
            '	</div>' +
            '</div>'
        );
        return AMBOverlay;
    });;;
    /*! RESOURCE: /scripts/bootstrap-datetimepicker.js */
    ;
    (function(root, factory) {
        'use strict';
        if (typeof define === 'function' && define.amd) {
            define(['jquery', 'moment'], factory);
        } else if (typeof exports === 'object') {
            factory(require('jquery'), require('moment'));
        } else {
            if (!jQuery) {
                throw new Error('bootstrap-datetimepicker requires jQuery to be loaded first');
            }
            if (!moment) {
                throw new Error('bootstrap-datetimepicker requires moment.js to be loaded first');
            }
            factory(root.jQuery, moment);
        }
    }(this, function($, moment) {
        'use strict';
        if (typeof moment === 'undefined') {
            throw new Error('momentjs is required');
        }
        var dpgId = 0,
            DateTimePicker = function(element, options) {
                var defaults = $.fn.datetimepicker.defaults,
                    icons = {
                        time: 'glyphicon glyphicon-time',
                        date: 'glyphicon glyphicon-calendar',
                        up: 'glyphicon glyphicon-chevron-up',
                        down: 'glyphicon glyphicon-chevron-down'
                    },
                    picker = this,
                    errored = false,
                    dDate,
                    init = function() {
                        var icon = false,
                            localeData, rInterval;
                        picker.options = $.extend({}, defaults, options);
                        picker.options.icons = $.extend({}, icons, picker.options.icons);
                        picker.element = $(element);
                        dataToOptions();
                        if (!(picker.options.pickTime || picker.options.pickDate)) {
                            throw new Error('Must choose at least one picker');
                        }
                        picker.id = dpgId++;
                        moment.locale(picker.options.language);
                        picker.date = moment();
                        picker.unset = false;
                        picker.isInput = picker.element.is('input');
                        picker.component = false;
                        if (picker.element.hasClass('input-group')) {
                            if (picker.element.find('.datepickerbutton').size() === 0) {
                                picker.component = picker.element.find('[class^="input-group-"]');
                            } else {
                                picker.component = picker.element.find('.datepickerbutton');
                            }
                        }
                        picker.format = picker.options.format;
                        localeData = moment().localeData();
                        if (!picker.format) {
                            picker.format = (picker.options.pickDate ? localeData.longDateFormat('L') : '');
                            if (picker.options.pickDate && picker.options.pickTime) {
                                picker.format += ' ';
                            }
                            picker.format += (picker.options.pickTime ? localeData.longDateFormat('LT') : '');
                            if (picker.options.useSeconds) {
                                if (localeData.longDateFormat('LT').indexOf(' A') !== -1) {
                                    picker.format = picker.format.split(' A')[0] + ':ss A';
                                } else {
                                    picker.format += ':ss';
                                }
                            }
                        }
                        picker.use24hours = (picker.format.toLowerCase().indexOf('a') < 0 && picker.format.indexOf('h') < 0);
                        if (picker.component) {
                            icon = picker.component.find('span');
                        }
                        if (picker.options.pickTime) {
                            if (icon) {
                                icon.addClass(picker.options.icons.time);
                            }
                        }
                        if (picker.options.pickDate) {
                            if (icon) {
                                icon.removeClass(picker.options.icons.time);
                                icon.addClass(picker.options.icons.date);
                            }
                        }
                        picker.options.widgetParent =
                            typeof picker.options.widgetParent === 'string' && picker.options.widgetParent ||
                            picker.element.parents().filter(function() {
                                return 'scroll' === $(this).css('overflow-y');
                            }).get(0) ||
                            'body';
                        picker.widget = $(getTemplate()).appendTo(picker.options.widgetParent);
                        picker.minViewMode = picker.options.minViewMode || 0;
                        if (typeof picker.minViewMode === 'string') {
                            switch (picker.minViewMode) {
                                case 'months':
                                    picker.minViewMode = 1;
                                    break;
                                case 'years':
                                    picker.minViewMode = 2;
                                    break;
                                default:
                                    picker.minViewMode = 0;
                                    break;
                            }
                        }
                        picker.viewMode = picker.options.viewMode || 0;
                        if (typeof picker.viewMode === 'string') {
                            switch (picker.viewMode) {
                                case 'months':
                                    picker.viewMode = 1;
                                    break;
                                case 'years':
                                    picker.viewMode = 2;
                                    break;
                                default:
                                    picker.viewMode = 0;
                                    break;
                            }
                        }
                        picker.viewMode = Math.max(picker.viewMode, picker.minViewMode);
                        picker.options.disabledDates = indexGivenDates(picker.options.disabledDates);
                        picker.options.enabledDates = indexGivenDates(picker.options.enabledDates);
                        picker.startViewMode = picker.viewMode;
                        picker.setMinDate(picker.options.minDate);
                        picker.setMaxDate(picker.options.maxDate);
                        fillDow();
                        fillMonths();
                        fillHours();
                        fillMinutes();
                        fillSeconds();
                        update();
                        showMode();
                        if (!getPickerInput().prop('disabled')) {
                            attachDatePickerEvents();
                        }
                        if (picker.options.defaultDate !== '' && getPickerInput().val() === '') {
                            picker.setValue(picker.options.defaultDate);
                        }
                        if (picker.options.minuteStepping !== 1) {
                            rInterval = picker.options.minuteStepping;
                            picker.date.minutes((Math.round(picker.date.minutes() / rInterval) * rInterval) % 60).seconds(0);
                        }
                    },
                    getPickerInput = function() {
                        var input;
                        if (picker.isInput) {
                            return picker.element;
                        }
                        input = picker.element.find('.datepickerinput');
                        if (input.size() === 0) {
                            input = picker.element.find('input');
                        } else if (!input.is('input')) {
                            throw new Error('CSS class "datepickerinput" cannot be applied to non input element');
                        }
                        return input;
                    },
                    dataToOptions = function() {
                        var eData;
                        if (picker.element.is('input')) {
                            eData = picker.element.data();
                        } else {
                            eData = picker.element.find('input').data();
                        }
                        if (eData.dateFormat !== undefined) {
                            picker.options.format = eData.dateFormat;
                        }
                        if (eData.datePickdate !== undefined) {
                            picker.options.pickDate = eData.datePickdate;
                        }
                        if (eData.datePicktime !== undefined) {
                            picker.options.pickTime = eData.datePicktime;
                        }
                        if (eData.dateUseminutes !== undefined) {
                            picker.options.useMinutes = eData.dateUseminutes;
                        }
                        if (eData.dateUseseconds !== undefined) {
                            picker.options.useSeconds = eData.dateUseseconds;
                        }
                        if (eData.dateUsecurrent !== undefined) {
                            picker.options.useCurrent = eData.dateUsecurrent;
                        }
                        if (eData.calendarWeeks !== undefined) {
                            picker.options.calendarWeeks = eData.calendarWeeks;
                        }
                        if (eData.dateMinutestepping !== undefined) {
                            picker.options.minuteStepping = eData.dateMinutestepping;
                        }
                        if (eData.dateMindate !== undefined) {
                            picker.options.minDate = eData.dateMindate;
                        }
                        if (eData.dateMaxdate !== undefined) {
                            picker.options.maxDate = eData.dateMaxdate;
                        }
                        if (eData.dateShowtoday !== undefined) {
                            picker.options.showToday = eData.dateShowtoday;
                        }
                        if (eData.dateCollapse !== undefined) {
                            picker.options.collapse = eData.dateCollapse;
                        }
                        if (eData.dateLanguage !== undefined) {
                            picker.options.language = eData.dateLanguage;
                        }
                        if (eData.dateDefaultdate !== undefined) {
                            picker.options.defaultDate = eData.dateDefaultdate;
                        }
                        if (eData.dateDisableddates !== undefined) {
                            picker.options.disabledDates = eData.dateDisableddates;
                        }
                        if (eData.dateEnableddates !== undefined) {
                            picker.options.enabledDates = eData.dateEnableddates;
                        }
                        if (eData.dateIcons !== undefined) {
                            picker.options.icons = eData.dateIcons;
                        }
                        if (eData.dateUsestrict !== undefined) {
                            picker.options.useStrict = eData.dateUsestrict;
                        }
                        if (eData.dateDirection !== undefined) {
                            picker.options.direction = eData.dateDirection;
                        }
                        if (eData.dateSidebyside !== undefined) {
                            picker.options.sideBySide = eData.dateSidebyside;
                        }
                        if (eData.dateDaysofweekdisabled !== undefined) {
                            picker.options.daysOfWeekDisabled = eData.dateDaysofweekdisabled;
                        }
                    },
                    place = function() {
                        var position = 'absolute',
                            offset = picker.component ? picker.component.offset() : picker.element.offset(),
                            $window = $(window),
                            placePosition;
                        picker.width = picker.component ? picker.component.outerWidth() : picker.element.outerWidth();
                        offset.top = offset.top + picker.element.outerHeight();
                        if (picker.options.direction === 'up') {
                            placePosition = 'top';
                        } else if (picker.options.direction === 'bottom') {
                            placePosition = 'bottom';
                        } else if (picker.options.direction === 'auto') {
                            if (offset.top + picker.widget.height() > $window.height() + $window.scrollTop() && picker.widget.height() + picker.element.outerHeight() < offset.top) {
                                placePosition = 'top';
                            } else {
                                placePosition = 'bottom';
                            }
                        }
                        if (placePosition === 'top') {
                            offset.top = offset.top - picker.element.outerHeight() - picker.widget.height() - 13;
                            picker.widget.addClass('top').removeClass('bottom');
                        } else {
                            offset.top += 1;
                            picker.widget.addClass('bottom').removeClass('top');
                        }
                        if (picker.options.width !== undefined) {
                            picker.widget.width(picker.options.width);
                        }
                        if (picker.options.orientation === 'left') {
                            picker.widget.addClass('left-oriented');
                            offset.left = offset.left - picker.widget.width() + 20;
                        }
                        if (isInFixed()) {
                            position = 'fixed';
                            offset.top -= $window.scrollTop();
                            offset.left -= $window.scrollLeft();
                        }
                        if ($window.width() < offset.left + picker.widget.outerWidth()) {
                            offset.right = $window.width() - offset.left - picker.width;
                            offset.left = 'auto';
                            picker.widget.addClass('pull-right');
                        } else {
                            offset.right = 'auto';
                            picker.widget.removeClass('pull-right');
                        }
                        if (placePosition === 'top') {
                            picker.widget.css({
                                position: position,
                                bottom: 'auto',
                                top: offset.top,
                                left: offset.left,
                                right: offset.right
                            });
                        } else {
                            picker.widget.css({
                                position: position,
                                top: offset.top,
                                bottom: 'auto',
                                left: offset.left,
                                right: offset.right
                            });
                        }
                    },
                    notifyChange = function(oldDate, eventType) {
                        if (moment(picker.date).isSame(moment(oldDate)) && !errored) {
                            return;
                        }
                        errored = false;
                        picker.element.trigger({
                            type: 'dp.change',
                            date: moment(picker.date),
                            oldDate: moment(oldDate)
                        });
                        if (eventType !== 'change') {
                            picker.element.change();
                        }
                    },
                    notifyError = function(date) {
                        errored = true;
                        picker.element.trigger({
                            type: 'dp.error',
                            date: moment(date, picker.format, picker.options.useStrict)
                        });
                    },
                    update = function(newDate) {
                        moment.locale(picker.options.language);
                        var dateStr = newDate;
                        if (!dateStr) {
                            dateStr = getPickerInput().val();
                            if (dateStr) {
                                picker.date = moment(dateStr, picker.format, picker.options.useStrict);
                            }
                            if (!picker.date) {
                                picker.date = moment();
                            }
                        }
                        picker.viewDate = moment(picker.date).startOf('month');
                        fillDate();
                        fillTime();
                    },
                    fillDow = function() {
                        moment.locale(picker.options.language);
                        var html = $('<tr>'),
                            weekdaysMin = moment.weekdaysMin(),
                            i;
                        if (picker.options.calendarWeeks === true) {
                            html.append('<th class="cw">#</th>');
                        }
                        if (moment().localeData()._week.dow === 0) {
                            for (i = 0; i < 7; i++) {
                                html.append('<th class="dow">' + weekdaysMin[i] + '</th>');
                            }
                        } else {
                            for (i = 1; i < 8; i++) {
                                if (i === 7) {
                                    html.append('<th class="dow">' + weekdaysMin[0] + '</th>');
                                } else {
                                    html.append('<th class="dow">' + weekdaysMin[i] + '</th>');
                                }
                            }
                        }
                        picker.widget.find('.datepicker-days thead').append(html);
                    },
                    fillMonths = function() {
                        moment.locale(picker.options.language);
                        var html = '',
                            i, monthsShort = moment.monthsShort();
                        for (i = 0; i < 12; i++) {
                            html += '<span class="month">' + monthsShort[i] + '</span>';
                        }
                        picker.widget.find('.datepicker-months td').append(html);
                    },
                    fillDate = function() {
                        if (!picker.options.pickDate) {
                            return;
                        }
                        moment.locale(picker.options.language);
                        var year = picker.viewDate.year(),
                            month = picker.viewDate.month(),
                            startYear = picker.options.minDate.year(),
                            startMonth = picker.options.minDate.month(),
                            endYear = picker.options.maxDate.year(),
                            endMonth = picker.options.maxDate.month(),
                            currentDate,
                            prevMonth, nextMonth, html = [],
                            row, clsName, i, days, yearCont, currentYear, months = moment.months();
                        picker.widget.find('.datepicker-days').find('.disabled').removeClass('disabled');
                        picker.widget.find('.datepicker-months').find('.disabled').removeClass('disabled');
                        picker.widget.find('.datepicker-years').find('.disabled').removeClass('disabled');
                        picker.widget.find('.datepicker-days th:eq(1)').text(
                            months[month] + ' ' + year);
                        prevMonth = moment(picker.viewDate, picker.format, picker.options.useStrict).subtract(1, 'months');
                        days = prevMonth.daysInMonth();
                        prevMonth.date(days).startOf('week');
                        if ((year === startYear && month <= startMonth) || year < startYear) {
                            picker.widget.find('.datepicker-days th:eq(0)').addClass('disabled');
                        }
                        if ((year === endYear && month >= endMonth) || year > endYear) {
                            picker.widget.find('.datepicker-days th:eq(2)').addClass('disabled');
                        }
                        nextMonth = moment(prevMonth).add(42, 'd');
                        while (prevMonth.isBefore(nextMonth)) {
                            if (prevMonth.weekday() === moment().startOf('week').weekday()) {
                                row = $('<tr>');
                                html.push(row);
                                if (picker.options.calendarWeeks === true) {
                                    row.append('<td class="cw">' + prevMonth.week() + '</td>');
                                }
                            }
                            clsName = '';
                            if (prevMonth.year() < year || (prevMonth.year() === year && prevMonth.month() < month)) {
                                clsName += ' old';
                            } else if (prevMonth.year() > year || (prevMonth.year() === year && prevMonth.month() > month)) {
                                clsName += ' new';
                            }
                            if (prevMonth.isSame(moment({
                                    y: picker.date.year(),
                                    M: picker.date.month(),
                                    d: picker.date.date()
                                }))) {
                                clsName += ' active';
                            }
                            if (isInDisableDates(prevMonth, 'day') || !isInEnableDates(prevMonth)) {
                                clsName += ' disabled';
                            }
                            if (picker.options.showToday === true) {
                                if (prevMonth.isSame(moment(), 'day')) {
                                    clsName += ' today';
                                }
                            }
                            if (picker.options.daysOfWeekDisabled) {
                                for (i = 0; i < picker.options.daysOfWeekDisabled.length; i++) {
                                    if (prevMonth.day() === picker.options.daysOfWeekDisabled[i]) {
                                        clsName += ' disabled';
                                        break;
                                    }
                                }
                            }
                            row.append('<td class="day' + clsName + '">' + prevMonth.date() + '</td>');
                            currentDate = prevMonth.date();
                            prevMonth.add(1, 'd');
                            if (currentDate === prevMonth.date()) {
                                prevMonth.add(1, 'd');
                            }
                        }
                        picker.widget.find('.datepicker-days tbody').empty().append(html);
                        currentYear = picker.date.year();
                        months = picker.widget.find('.datepicker-months').find('th:eq(1)').text(year).end().find('span').removeClass('active');
                        if (currentYear === year) {
                            months.eq(picker.date.month()).addClass('active');
                        }
                        if (year - 1 < startYear) {
                            picker.widget.find('.datepicker-months th:eq(0)').addClass('disabled');
                        }
                        if (year + 1 > endYear) {
                            picker.widget.find('.datepicker-months th:eq(2)').addClass('disabled');
                        }
                        for (i = 0; i < 12; i++) {
                            if ((year === startYear && startMonth > i) || (year < startYear)) {
                                $(months[i]).addClass('disabled');
                            } else if ((year === endYear && endMonth < i) || (year > endYear)) {
                                $(months[i]).addClass('disabled');
                            }
                        }
                        html = '';
                        year = parseInt(year / 10, 10) * 10;
                        yearCont = picker.widget.find('.datepicker-years').find(
                            'th:eq(1)').text(year + '-' + (year + 9)).parents('table').find('td');
                        picker.widget.find('.datepicker-years').find('th').removeClass('disabled');
                        if (startYear > year) {
                            picker.widget.find('.datepicker-years').find('th:eq(0)').addClass('disabled');
                        }
                        if (endYear < year + 9) {
                            picker.widget.find('.datepicker-years').find('th:eq(2)').addClass('disabled');
                        }
                        year -= 1;
                        for (i = -1; i < 11; i++) {
                            html += '<span class="year' + (i === -1 || i === 10 ? ' old' : '') + (currentYear === year ? ' active' : '') + ((year < startYear || year > endYear) ? ' disabled' : '') + '">' + year + '</span>';
                            year += 1;
                        }
                        yearCont.html(html);
                    },
                    fillHours = function() {
                        moment.locale(picker.options.language);
                        var table = picker.widget.find('.timepicker .timepicker-hours table'),
                            html = '',
                            current, i, j;
                        table.parent().hide();
                        if (picker.use24hours) {
                            current = 0;
                            for (i = 0; i < 6; i += 1) {
                                html += '<tr>';
                                for (j = 0; j < 4; j += 1) {
                                    html += '<td class="hour">' + padLeft(current.toString()) + '</td>';
                                    current++;
                                }
                                html += '</tr>';
                            }
                        } else {
                            current = 1;
                            for (i = 0; i < 3; i += 1) {
                                html += '<tr>';
                                for (j = 0; j < 4; j += 1) {
                                    html += '<td class="hour">' + padLeft(current.toString()) + '</td>';
                                    current++;
                                }
                                html += '</tr>';
                            }
                        }
                        table.html(html);
                    },
                    fillMinutes = function() {
                        var table = picker.widget.find('.timepicker .timepicker-minutes table'),
                            html = '',
                            current = 0,
                            i, j, step = picker.options.minuteStepping;
                        table.parent().hide();
                        if (step === 1) {
                            step = 5;
                        }
                        for (i = 0; i < Math.ceil(60 / step / 4); i++) {
                            html += '<tr>';
                            for (j = 0; j < 4; j += 1) {
                                if (current < 60) {
                                    html += '<td class="minute">' + padLeft(current.toString()) + '</td>';
                                    current += step;
                                } else {
                                    html += '<td></td>';
                                }
                            }
                            html += '</tr>';
                        }
                        table.html(html);
                    },
                    fillSeconds = function() {
                        var table = picker.widget.find('.timepicker .timepicker-seconds table'),
                            html = '',
                            current = 0,
                            i, j;
                        table.parent().hide();
                        for (i = 0; i < 3; i++) {
                            html += '<tr>';
                            for (j = 0; j < 4; j += 1) {
                                html += '<td class="second">' + padLeft(current.toString()) + '</td>';
                                current += 5;
                            }
                            html += '</tr>';
                        }
                        table.html(html);
                    },
                    fillTime = function() {
                        if (!picker.date) {
                            return;
                        }
                        var timeComponents = picker.widget.find('.timepicker span[data-time-component]'),
                            hour = picker.date.hours(),
                            period = picker.date.format('A');
                        if (!picker.use24hours) {
                            if (hour === 0) {
                                hour = 12;
                            } else if (hour !== 12) {
                                hour = hour % 12;
                            }
                            picker.widget.find('.timepicker [data-action=togglePeriod]').text(period);
                        }
                        timeComponents.filter('[data-time-component=hours]').text(padLeft(hour));
                        timeComponents.filter('[data-time-component=minutes]').text(padLeft(picker.date.minutes()));
                        timeComponents.filter('[data-time-component=seconds]').text(padLeft(picker.date.second()));
                    },
                    click = function(e) {
                        e.stopPropagation();
                        e.preventDefault();
                        picker.unset = false;
                        var target = $(e.target).closest('span, td, th'),
                            month, year, step, day, oldDate = moment(picker.date);
                        if (target.length === 1) {
                            if (!target.is('.disabled')) {
                                switch (target[0].nodeName.toLowerCase()) {
                                    case 'th':
                                        switch (target[0].className) {
                                            case 'picker-switch':
                                                showMode(1);
                                                break;
                                            case 'prev':
                                            case 'next':
                                                step = dpGlobal.modes[picker.viewMode].navStep;
                                                if (target[0].className === 'prev') {
                                                    step = step * -1;
                                                }
                                                picker.viewDate.add(step, dpGlobal.modes[picker.viewMode].navFnc);
                                                fillDate();
                                                break;
                                        }
                                        break;
                                    case 'span':
                                        if (target.is('.month')) {
                                            month = target.parent().find('span').index(target);
                                            picker.viewDate.month(month);
                                        } else {
                                            year = parseInt(target.text(), 10) || 0;
                                            picker.viewDate.year(year);
                                        }
                                        if (picker.viewMode === picker.minViewMode) {
                                            picker.date = moment({
                                                y: picker.viewDate.year(),
                                                M: picker.viewDate.month(),
                                                d: picker.viewDate.date(),
                                                h: picker.date.hours(),
                                                m: picker.date.minutes(),
                                                s: picker.date.seconds()
                                            });
                                            set();
                                            notifyChange(oldDate, e.type);
                                        }
                                        showMode(-1);
                                        fillDate();
                                        break;
                                    case 'td':
                                        if (target.is('.day')) {
                                            day = parseInt(target.text(), 10) || 1;
                                            month = picker.viewDate.month();
                                            year = picker.viewDate.year();
                                            if (target.is('.old')) {
                                                if (month === 0) {
                                                    month = 11;
                                                    year -= 1;
                                                } else {
                                                    month -= 1;
                                                }
                                            } else if (target.is('.new')) {
                                                if (month === 11) {
                                                    month = 0;
                                                    year += 1;
                                                } else {
                                                    month += 1;
                                                }
                                            }
                                            picker.date = moment({
                                                y: year,
                                                M: month,
                                                d: day,
                                                h: picker.date.hours(),
                                                m: picker.date.minutes(),
                                                s: picker.date.seconds()
                                            });
                                            picker.viewDate = moment({
                                                y: year,
                                                M: month,
                                                d: Math.min(28, day)
                                            });
                                            fillDate();
                                            set();
                                            notifyChange(oldDate, e.type);
                                        }
                                        break;
                                }
                            }
                        }
                    },
                    actions = {
                        incrementHours: function() {
                            checkDate('add', 'hours', 1);
                        },
                        incrementMinutes: function() {
                            checkDate('add', 'minutes', picker.options.minuteStepping);
                        },
                        incrementSeconds: function() {
                            checkDate('add', 'seconds', 1);
                        },
                        decrementHours: function() {
                            checkDate('subtract', 'hours', 1);
                        },
                        decrementMinutes: function() {
                            checkDate('subtract', 'minutes', picker.options.minuteStepping);
                        },
                        decrementSeconds: function() {
                            checkDate('subtract', 'seconds', 1);
                        },
                        togglePeriod: function() {
                            var hour = picker.date.hours();
                            if (hour >= 12) {
                                hour -= 12;
                            } else {
                                hour += 12;
                            }
                            picker.date.hours(hour);
                        },
                        showPicker: function() {
                            picker.widget.find('.timepicker > div:not(.timepicker-picker)').hide();
                            picker.widget.find('.timepicker .timepicker-picker').show();
                        },
                        showHours: function() {
                            picker.widget.find('.timepicker .timepicker-picker').hide();
                            picker.widget.find('.timepicker .timepicker-hours').show();
                        },
                        showMinutes: function() {
                            picker.widget.find('.timepicker .timepicker-picker').hide();
                            picker.widget.find('.timepicker .timepicker-minutes').show();
                        },
                        showSeconds: function() {
                            picker.widget.find('.timepicker .timepicker-picker').hide();
                            picker.widget.find('.timepicker .timepicker-seconds').show();
                        },
                        selectHour: function(e) {
                            var hour = parseInt($(e.target).text(), 10);
                            if (!picker.use24hours) {
                                if (picker.date.hours() >= 12) {
                                    if (hour !== 12) {
                                        hour += 12;
                                    }
                                } else {
                                    if (hour === 12) {
                                        hour = 0;
                                    }
                                }
                            }
                            picker.date.hours(hour);
                            actions.showPicker.call(picker);
                        },
                        selectMinute: function(e) {
                            picker.date.minutes(parseInt($(e.target).text(), 10));
                            actions.showPicker.call(picker);
                        },
                        selectSecond: function(e) {
                            picker.date.seconds(parseInt($(e.target).text(), 10));
                            actions.showPicker.call(picker);
                        }
                    },
                    doAction = function(e) {
                        var oldDate = moment(picker.date),
                            action = $(e.currentTarget).data('action'),
                            rv = actions[action].apply(picker, arguments);
                        stopEvent(e);
                        if (!picker.date) {
                            picker.date = moment({
                                y: 1970
                            });
                        }
                        set();
                        fillTime();
                        notifyChange(oldDate, e.type);
                        return rv;
                    },
                    stopEvent = function(e) {
                        e.stopPropagation();
                        e.preventDefault();
                    },
                    keydown = function(e) {
                        if (e.keyCode === 27) {
                            picker.hide();
                        }
                    },
                    change = function(e) {
                        moment.locale(picker.options.language);
                        var input = $(e.target),
                            oldDate = moment(picker.date),
                            newDate = moment(input.val(), picker.format, picker.options.useStrict);
                        if (newDate.isValid() && !isInDisableDates(newDate) && isInEnableDates(newDate)) {
                            update();
                            picker.setValue(newDate);
                            notifyChange(oldDate, e.type);
                            set();
                        } else {
                            picker.viewDate = oldDate;
                            picker.unset = true;
                            notifyChange(oldDate, e.type);
                            notifyError(newDate);
                        }
                    },
                    showMode = function(dir) {
                        if (dir) {
                            picker.viewMode = Math.max(picker.minViewMode, Math.min(2, picker.viewMode + dir));
                        }
                        picker.widget.find('.datepicker > div').hide().filter('.datepicker-' + dpGlobal.modes[picker.viewMode].clsName).show();
                    },
                    attachDatePickerEvents = function() {
                        var $this, $parent, expanded, closed, collapseData;
                        picker.widget.on('click', '.datepicker *', $.proxy(click, this));
                        picker.widget.on('click', '[data-action]', $.proxy(doAction, this));
                        picker.widget.on('mousedown', $.proxy(stopEvent, this));
                        picker.element.on('keydown', $.proxy(keydown, this));
                        if (picker.options.pickDate && picker.options.pickTime) {
                            picker.widget.on('click.togglePicker', '.accordion-toggle', function(e) {
                                e.stopPropagation();
                                $this = $(this);
                                $parent = $this.closest('ul');
                                expanded = $parent.find('.in');
                                closed = $parent.find('.collapse:not(.in)');
                                if (expanded && expanded.length) {
                                    collapseData = expanded.data('collapse');
                                    if (collapseData && collapseData.transitioning) {
                                        return;
                                    }
                                    expanded.collapse('hide');
                                    closed.collapse('show');
                                    $this.find('span').toggleClass(picker.options.icons.time + ' ' + picker.options.icons.date);
                                    if (picker.component) {
                                        picker.component.find('span').toggleClass(picker.options.icons.time + ' ' + picker.options.icons.date);
                                    }
                                }
                            });
                        }
                        if (picker.isInput) {
                            picker.element.on({
                                'click': $.proxy(picker.show, this),
                                'focus': $.proxy(picker.show, this),
                                'change': $.proxy(change, this),
                                'blur': $.proxy(picker.hide, this)
                            });
                        } else {
                            picker.element.on({
                                'change': $.proxy(change, this)
                            }, 'input');
                            if (picker.component) {
                                picker.component.on('click', $.proxy(picker.show, this));
                                picker.component.on('mousedown', $.proxy(stopEvent, this));
                            } else {
                                picker.element.on('click', $.proxy(picker.show, this));
                            }
                        }
                    },
                    attachDatePickerGlobalEvents = function() {
                        $(window).on(
                            'resize.datetimepicker' + picker.id, $.proxy(place, this));
                        if (!picker.isInput) {
                            $(document).on(
                                'mousedown.datetimepicker' + picker.id, $.proxy(picker.hide, this));
                        }
                    },
                    detachDatePickerEvents = function() {
                        picker.widget.off('click', '.datepicker *', picker.click);
                        picker.widget.off('click', '[data-action]');
                        picker.widget.off('mousedown', picker.stopEvent);
                        if (picker.options.pickDate && picker.options.pickTime) {
                            picker.widget.off('click.togglePicker');
                        }
                        if (picker.isInput) {
                            picker.element.off({
                                'focus': picker.show,
                                'change': change,
                                'click': picker.show,
                                'blur': picker.hide
                            });
                        } else {
                            picker.element.off({
                                'change': change
                            }, 'input');
                            if (picker.component) {
                                picker.component.off('click', picker.show);
                                picker.component.off('mousedown', picker.stopEvent);
                            } else {
                                picker.element.off('click', picker.show);
                            }
                        }
                    },
                    detachDatePickerGlobalEvents = function() {
                        $(window).off('resize.datetimepicker' + picker.id);
                        if (!picker.isInput) {
                            $(document).off('mousedown.datetimepicker' + picker.id);
                        }
                    },
                    isInFixed = function() {
                        if (picker.element) {
                            var parents = picker.element.parents(),
                                inFixed = false,
                                i;
                            for (i = 0; i < parents.length; i++) {
                                if ($(parents[i]).css('position') === 'fixed') {
                                    inFixed = true;
                                    break;
                                }
                            }
                            return inFixed;
                        } else {
                            return false;
                        }
                    },
                    set = function() {
                        moment.locale(picker.options.language);
                        var formatted = '';
                        if (!picker.unset) {
                            formatted = moment(picker.date).format(picker.format);
                        }
                        getPickerInput().val(formatted);
                        picker.element.data('date', formatted);
                        if (!picker.options.pickTime) {
                            picker.hide();
                        }
                    },
                    checkDate = function(direction, unit, amount) {
                        moment.locale(picker.options.language);
                        var newDate;
                        if (direction === 'add') {
                            newDate = moment(picker.date);
                            if (newDate.hours() === 23) {
                                newDate.add(amount, unit);
                            }
                            newDate.add(amount, unit);
                        } else {
                            newDate = moment(picker.date).subtract(amount, unit);
                        }
                        if (isInDisableDates(moment(newDate.subtract(amount, unit))) || isInDisableDates(newDate)) {
                            notifyError(newDate.format(picker.format));
                            return;
                        }
                        if (direction === 'add') {
                            picker.date.add(amount, unit);
                        } else {
                            picker.date.subtract(amount, unit);
                        }
                        picker.unset = false;
                    },
                    isInDisableDates = function(date, timeUnit) {
                        moment.locale(picker.options.language);
                        var maxDate = moment(picker.options.maxDate, picker.format, picker.options.useStrict),
                            minDate = moment(picker.options.minDate, picker.format, picker.options.useStrict);
                        if (timeUnit) {
                            maxDate = maxDate.endOf(timeUnit);
                            minDate = minDate.startOf(timeUnit);
                        }
                        if (date.isAfter(maxDate) || date.isBefore(minDate)) {
                            return true;
                        }
                        if (picker.options.disabledDates === false) {
                            return false;
                        }
                        return picker.options.disabledDates[date.format('YYYY-MM-DD')] === true;
                    },
                    isInEnableDates = function(date) {
                        moment.locale(picker.options.language);
                        if (picker.options.enabledDates === false) {
                            return true;
                        }
                        return picker.options.enabledDates[date.format('YYYY-MM-DD')] === true;
                    },
                    indexGivenDates = function(givenDatesArray) {
                        var givenDatesIndexed = {},
                            givenDatesCount = 0,
                            i;
                        for (i = 0; i < givenDatesArray.length; i++) {
                            if (moment.isMoment(givenDatesArray[i]) || givenDatesArray[i] instanceof Date) {
                                dDate = moment(givenDatesArray[i]);
                            } else {
                                dDate = moment(givenDatesArray[i], picker.format, picker.options.useStrict);
                            }
                            if (dDate.isValid()) {
                                givenDatesIndexed[dDate.format('YYYY-MM-DD')] = true;
                                givenDatesCount++;
                            }
                        }
                        if (givenDatesCount > 0) {
                            return givenDatesIndexed;
                        }
                        return false;
                    },
                    padLeft = function(string) {
                        string = string.toString();
                        if (string.length >= 2) {
                            return string;
                        }
                        return '0' + string;
                    },
                    getTemplate = function() {
                        var
                            headTemplate =
                            '<thead>' +
                            '<tr>' +
                            '<th class="prev">&lsaquo;</th><th colspan="' + (picker.options.calendarWeeks ? '6' : '5') + '" class="picker-switch"></th><th class="next">&rsaquo;</th>' +
                            '</tr>' +
                            '</thead>',
                            contTemplate =
                            '<tbody><tr><td colspan="' + (picker.options.calendarWeeks ? '8' : '7') + '"></td></tr></tbody>',
                            template = '<div class="datepicker-days">' +
                            '<table class="table-condensed">' + headTemplate + '<tbody></tbody></table>' +
                            '</div>' +
                            '<div class="datepicker-months">' +
                            '<table class="table-condensed">' + headTemplate + contTemplate + '</table>' +
                            '</div>' +
                            '<div class="datepicker-years">' +
                            '<table class="table-condensed">' + headTemplate + contTemplate + '</table>' +
                            '</div>',
                            ret = '';
                        if (picker.options.pickDate && picker.options.pickTime) {
                            ret = '<div class="bootstrap-datetimepicker-widget' + (picker.options.sideBySide ? ' timepicker-sbs' : '') + (picker.use24hours ? ' usetwentyfour' : '') + ' dropdown-menu" style="z-index:9999 !important;">';
                            if (picker.options.sideBySide) {
                                ret += '<div class="row">' +
                                    '<div class="col-sm-6 datepicker">' + template + '</div>' +
                                    '<div class="col-sm-6 timepicker">' + tpGlobal.getTemplate() + '</div>' +
                                    '</div>';
                            } else {
                                ret += '<ul class="list-unstyled">' +
                                    '<li' + (picker.options.collapse ? ' class="collapse in"' : '') + '>' +
                                    '<div class="datepicker">' + template + '</div>' +
                                    '</li>' +
                                    '<li class="picker-switch accordion-toggle"><a class="btn" style="width:100%"><span class="' + picker.options.icons.time + '"></span></a></li>' +
                                    '<li' + (picker.options.collapse ? ' class="collapse"' : '') + '>' +
                                    '<div class="timepicker">' + tpGlobal.getTemplate() + '</div>' +
                                    '</li>' +
                                    '</ul>';
                            }
                            ret += '</div>';
                            return ret;
                        }
                        if (picker.options.pickTime) {
                            return (
                                '<div class="bootstrap-datetimepicker-widget dropdown-menu">' +
                                '<div class="timepicker">' + tpGlobal.getTemplate() + '</div>' +
                                '</div>'
                            );
                        }
                        return (
                            '<div class="bootstrap-datetimepicker-widget dropdown-menu">' +
                            '<div class="datepicker">' + template + '</div>' +
                            '</div>'
                        );
                    },
                    dpGlobal = {
                        modes: [{
                                clsName: 'days',
                                navFnc: 'month',
                                navStep: 1
                            },
                            {
                                clsName: 'months',
                                navFnc: 'year',
                                navStep: 1
                            },
                            {
                                clsName: 'years',
                                navFnc: 'year',
                                navStep: 10
                            }
                        ]
                    },
                    tpGlobal = {
                        hourTemplate: '<span data-action="showHours"   data-time-component="hours"   class="timepicker-hour"></span>',
                        minuteTemplate: '<span data-action="showMinutes" data-time-component="minutes" class="timepicker-minute"></span>',
                        secondTemplate: '<span data-action="showSeconds"  data-time-component="seconds" class="timepicker-second"></span>'
                    };
                tpGlobal.getTemplate = function() {
                    return (
                        '<div class="timepicker-picker">' +
                        '<table class="table-condensed">' +
                        '<tr>' +
                        '<td><a href="#" class="btn" data-action="incrementHours"><span class="' + picker.options.icons.up + '"></span></a></td>' +
                        '<td class="separator"></td>' +
                        '<td>' + (picker.options.useMinutes ? '<a href="#" class="btn" data-action="incrementMinutes"><span class="' + picker.options.icons.up + '"></span></a>' : '') + '</td>' +
                        (picker.options.useSeconds ?
                            '<td class="separator"></td><td><a href="#" class="btn" data-action="incrementSeconds"><span class="' + picker.options.icons.up + '"></span></a></td>' : '') +
                        (picker.use24hours ? '' : '<td class="separator"></td>') +
                        '</tr>' +
                        '<tr>' +
                        '<td>' + tpGlobal.hourTemplate + '</td> ' +
                        '<td class="separator">:</td>' +
                        '<td>' + (picker.options.useMinutes ? tpGlobal.minuteTemplate : '<span class="timepicker-minute">00</span>') + '</td> ' +
                        (picker.options.useSeconds ?
                            '<td class="separator">:</td><td>' + tpGlobal.secondTemplate + '</td>' : '') +
                        (picker.use24hours ? '' : '<td class="separator"></td>' +
                            '<td><button type="button" class="btn btn-primary" data-action="togglePeriod"></button></td>') +
                        '</tr>' +
                        '<tr>' +
                        '<td><a href="#" class="btn" data-action="decrementHours"><span class="' + picker.options.icons.down + '"></span></a></td>' +
                        '<td class="separator"></td>' +
                        '<td>' + (picker.options.useMinutes ? '<a href="#" class="btn" data-action="decrementMinutes"><span class="' + picker.options.icons.down + '"></span></a>' : '') + '</td>' +
                        (picker.options.useSeconds ?
                            '<td class="separator"></td><td><a href="#" class="btn" data-action="decrementSeconds"><span class="' + picker.options.icons.down + '"></span></a></td>' : '') +
                        (picker.use24hours ? '' : '<td class="separator"></td>') +
                        '</tr>' +
                        '</table>' +
                        '</div>' +
                        '<div class="timepicker-hours" data-action="selectHour">' +
                        '<table class="table-condensed"></table>' +
                        '</div>' +
                        '<div class="timepicker-minutes" data-action="selectMinute">' +
                        '<table class="table-condensed"></table>' +
                        '</div>' +
                        (picker.options.useSeconds ?
                            '<div class="timepicker-seconds" data-action="selectSecond"><table class="table-condensed"></table></div>' : '')
                    );
                };
                picker.destroy = function() {
                    detachDatePickerEvents();
                    detachDatePickerGlobalEvents();
                    picker.widget.remove();
                    picker.element.removeData('DateTimePicker');
                    if (picker.component) {
                        picker.component.removeData('DateTimePicker');
                    }
                };
                picker.show = function(e) {
                    if (getPickerInput().prop('disabled')) {
                        return;
                    }
                    if (picker.options.useCurrent) {
                        if (getPickerInput().val() === '') {
                            if (picker.options.minuteStepping !== 1) {
                                var mDate = moment(),
                                    rInterval = picker.options.minuteStepping;
                                mDate.minutes((Math.round(mDate.minutes() / rInterval) * rInterval) % 60).seconds(0);
                                picker.setValue(mDate.format(picker.format));
                            } else {
                                picker.setValue(moment().format(picker.format));
                            }
                            notifyChange('', e.type);
                        }
                    }
                    if (e && e.type === 'click' && picker.isInput && picker.widget.hasClass('picker-open')) {
                        return;
                    }
                    if (picker.widget.hasClass('picker-open')) {
                        picker.widget.hide();
                        picker.widget.removeClass('picker-open');
                    } else {
                        picker.widget.show();
                        picker.widget.addClass('picker-open');
                    }
                    picker.height = picker.component ? picker.component.outerHeight() : picker.element.outerHeight();
                    place();
                    picker.element.trigger({
                        type: 'dp.show',
                        date: moment(picker.date)
                    });
                    attachDatePickerGlobalEvents();
                    if (e) {
                        stopEvent(e);
                    }
                };
                picker.disable = function() {
                    var input = getPickerInput();
                    if (input.prop('disabled')) {
                        return;
                    }
                    input.prop('disabled', true);
                    detachDatePickerEvents();
                };
                picker.enable = function() {
                    var input = getPickerInput();
                    if (!input.prop('disabled')) {
                        return;
                    }
                    input.prop('disabled', false);
                    attachDatePickerEvents();
                };
                picker.hide = function() {
                    var collapse = picker.widget.find('.collapse'),
                        i, collapseData;
                    for (i = 0; i < collapse.length; i++) {
                        collapseData = collapse.eq(i).data('collapse');
                        if (collapseData && collapseData.transitioning) {
                            return;
                        }
                    }
                    picker.widget.hide();
                    picker.widget.removeClass('picker-open');
                    picker.viewMode = picker.startViewMode;
                    showMode();
                    picker.element.trigger({
                        type: 'dp.hide',
                        date: moment(picker.date)
                    });
                    detachDatePickerGlobalEvents();
                };
                picker.setValue = function(newDate) {
                    moment.locale(picker.options.language);
                    if (!newDate) {
                        picker.unset = true;
                        set();
                    } else {
                        picker.unset = false;
                    }
                    if (!moment.isMoment(newDate)) {
                        newDate = (newDate instanceof Date) ? moment(newDate) : moment(newDate, picker.format, picker.options.useStrict);
                    } else {
                        newDate = newDate.locale(picker.options.language);
                    }
                    if (newDate.isValid()) {
                        picker.date = newDate;
                        set();
                        picker.viewDate = moment({
                            y: picker.date.year(),
                            M: picker.date.month()
                        });
                        fillDate();
                        fillTime();
                    } else {
                        notifyError(newDate);
                    }
                };
                picker.getDate = function() {
                    if (picker.unset) {
                        return null;
                    }
                    return moment(picker.date);
                };
                picker.setDate = function(date) {
                    var oldDate = moment(picker.date);
                    if (!date) {
                        picker.setValue(null);
                    } else {
                        picker.setValue(date);
                    }
                    notifyChange(oldDate, 'function');
                };
                picker.setDisabledDates = function(dates) {
                    picker.options.disabledDates = indexGivenDates(dates);
                    if (picker.viewDate) {
                        update();
                    }
                };
                picker.setEnabledDates = function(dates) {
                    picker.options.enabledDates = indexGivenDates(dates);
                    if (picker.viewDate) {
                        update();
                    }
                };
                picker.setMaxDate = function(date) {
                    if (date === undefined) {
                        return;
                    }
                    if (moment.isMoment(date) || date instanceof Date) {
                        picker.options.maxDate = moment(date);
                    } else {
                        picker.options.maxDate = moment(date, picker.format, picker.options.useStrict);
                    }
                    if (picker.viewDate) {
                        update();
                    }
                };
                picker.setMinDate = function(date) {
                    if (date === undefined) {
                        return;
                    }
                    if (moment.isMoment(date) || date instanceof Date) {
                        picker.options.minDate = moment(date);
                    } else {
                        picker.options.minDate = moment(date, picker.format, picker.options.useStrict);
                    }
                    if (picker.viewDate) {
                        update();
                    }
                };
                init();
            };
        $.fn.datetimepicker = function(options) {
            return this.each(function() {
                var $this = $(this),
                    data = $this.data('DateTimePicker');
                if (!data) {
                    $this.data('DateTimePicker', new DateTimePicker(this, options));
                }
            });
        };
        $.fn.datetimepicker.defaults = {
            format: false,
            pickDate: true,
            pickTime: true,
            useMinutes: true,
            useSeconds: false,
            useCurrent: true,
            calendarWeeks: false,
            minuteStepping: 1,
            minDate: moment({
                y: 1900
            }),
            maxDate: moment().add(100, 'y'),
            showToday: true,
            collapse: true,
            language: moment.locale(),
            defaultDate: '',
            disabledDates: false,
            enabledDates: false,
            icons: {},
            useStrict: false,
            direction: 'auto',
            sideBySide: false,
            daysOfWeekDisabled: [],
            widgetParent: false
        };
    }));;
    /*! RESOURCE: /scripts/libs/sortable.min.js */
    /*! Sortable 1.4.2 - MIT | git://github.com/rubaxa/Sortable.git */
    ! function(a) {
        "use strict";
        "function" == typeof define && define.amd ? define(a) : "undefined" != typeof module && "undefined" != typeof module.exports ? module.exports = a() : "undefined" != typeof Package ? Sortable = a() : window.Sortable = a()
    }(function() {
        "use strict";
    
        function a(a, b) {
            if (!a || !a.nodeType || 1 !== a.nodeType) throw "Sortable: `el` must be HTMLElement, and not " + {}.toString.call(a);
            this.el = a, this.options = b = r({}, b), a[L] = this;
            var c = {
                group: Math.random(),
                sort: !0,
                disabled: !1,
                store: null,
                handle: null,
                scroll: !0,
                scrollSensitivity: 30,
                scrollSpeed: 10,
                draggable: /[uo]l/i.test(a.nodeName) ? "li" : ">*",
                ghostClass: "sortable-ghost",
                chosenClass: "sortable-chosen",
                ignore: "a, img",
                filter: null,
                animation: 0,
                setData: function(a, b) {
                    a.setData("Text", b.textContent)
                },
                dropBubble: !1,
                dragoverBubble: !1,
                dataIdAttr: "data-id",
                delay: 0,
                forceFallback: !1,
                fallbackClass: "sortable-fallback",
                fallbackOnBody: !1
            };
            for (var d in c) !(d in b) && (b[d] = c[d]);
            V(b);
            for (var f in this) "_" === f.charAt(0) && (this[f] = this[f].bind(this));
            this.nativeDraggable = b.forceFallback ? !1 : P, e(a, "mousedown", this._onTapStart), e(a, "touchstart", this._onTapStart), this.nativeDraggable && (e(a, "dragover", this), e(a, "dragenter", this)), T.push(this._onDragOver), b.store && this.sort(b.store.get(this))
        }
    
        function b(a) {
            v && v.state !== a && (h(v, "display", a ? "none" : ""), !a && v.state && w.insertBefore(v, s), v.state = a)
        }
    
        function c(a, b, c) {
            if (a) {
                c = c || N, b = b.split(".");
                var d = b.shift().toUpperCase(),
                    e = new RegExp("\\s(" + b.join("|") + ")(?=\\s)", "g");
                do
                    if (">*" === d && a.parentNode === c || ("" === d || a.nodeName.toUpperCase() == d) && (!b.length || ((" " + a.className + " ").match(e) || []).length == b.length)) return a; while (a !== c && (a = a.parentNode))
            }
            return null
        }
    
        function d(a) {
            a.dataTransfer && (a.dataTransfer.dropEffect = "move"), a.preventDefault()
        }
    
        function e(a, b, c) {
            a.addEventListener(b, c, !1)
        }
    
        function f(a, b, c) {
            a.removeEventListener(b, c, !1)
        }
    
        function g(a, b, c) {
            if (a)
                if (a.classList) a.classList[c ? "add" : "remove"](b);
                else {
                    var d = (" " + a.className + " ").replace(K, " ").replace(" " + b + " ", " ");
                    a.className = (d + (c ? " " + b : "")).replace(K, " ")
                }
        }
    
        function h(a, b, c) {
            var d = a && a.style;
            if (d) {
                if (void 0 === c) return N.defaultView && N.defaultView.getComputedStyle ? c = N.defaultView.getComputedStyle(a, "") : a.currentStyle && (c = a.currentStyle), void 0 === b ? c : c[b];
                b in d || (b = "-webkit-" + b), d[b] = c + ("string" == typeof c ? "" : "px")
            }
        }
    
        function i(a, b, c) {
            if (a) {
                var d = a.getElementsByTagName(b),
                    e = 0,
                    f = d.length;
                if (c)
                    for (; f > e; e++) c(d[e], e);
                return d
            }
            return []
        }
    
        function j(a, b, c, d, e, f, g) {
            var h = N.createEvent("Event"),
                i = (a || b[L]).options,
                j = "on" + c.charAt(0).toUpperCase() + c.substr(1);
            h.initEvent(c, !0, !0), h.to = b, h.from = e || b, h.item = d || b, h.clone = v, h.oldIndex = f, h.newIndex = g, b.dispatchEvent(h), i[j] && i[j].call(a, h)
        }
    
        function k(a, b, c, d, e, f) {
            var g, h, i = a[L],
                j = i.options.onMove;
            return g = N.createEvent("Event"), g.initEvent("move", !0, !0), g.to = b, g.from = a, g.dragged = c, g.draggedRect = d, g.related = e || b, g.relatedRect = f || b.getBoundingClientRect(), a.dispatchEvent(g), j && (h = j.call(i, g)), h
        }
    
        function l(a) {
            a.draggable = !1
        }
    
        function m() {
            R = !1
        }
    
        function n(a, b) {
            var c = a.lastElementChild,
                d = c.getBoundingClientRect();
            return (b.clientY - (d.top + d.height) > 5 || b.clientX - (d.right + d.width) > 5) && c
        }
    
        function o(a) {
            for (var b = a.tagName + a.className + a.src + a.href + a.textContent, c = b.length, d = 0; c--;) d += b.charCodeAt(c);
            return d.toString(36)
        }
    
        function p(a) {
            var b = 0;
            if (!a || !a.parentNode) return -1;
            for (; a && (a = a.previousElementSibling);) "TEMPLATE" !== a.nodeName.toUpperCase() && b++;
            return b
        }
    
        function q(a, b) {
            var c, d;
            return function() {
                void 0 === c && (c = arguments, d = this, setTimeout(function() {
                    1 === c.length ? a.call(d, c[0]) : a.apply(d, c), c = void 0
                }, b))
            }
        }
    
        function r(a, b) {
            if (a && b)
                for (var c in b) b.hasOwnProperty(c) && (a[c] = b[c]);
            return a
        }
        var s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J = {},
            K = /\s+/g,
            L = "Sortable" + (new Date).getTime(),
            M = window,
            N = M.document,
            O = M.parseInt,
            P = !!("draggable" in N.createElement("div")),
            Q = function(a) {
                return a = N.createElement("x"), a.style.cssText = "pointer-events:auto", "auto" === a.style.pointerEvents
            }(),
            R = !1,
            S = Math.abs,
            T = ([].slice, []),
            U = q(function(a, b, c) {
                if (c && b.scroll) {
                    var d, e, f, g, h = b.scrollSensitivity,
                        i = b.scrollSpeed,
                        j = a.clientX,
                        k = a.clientY,
                        l = window.innerWidth,
                        m = window.innerHeight;
                    if (z !== c && (y = b.scroll, z = c, y === !0)) {
                        y = c;
                        do
                            if (y.offsetWidth < y.scrollWidth || y.offsetHeight < y.scrollHeight) break; while (y = y.parentNode)
                    }
                    y && (d = y, e = y.getBoundingClientRect(), f = (S(e.right - j) <= h) - (S(e.left - j) <= h), g = (S(e.bottom - k) <= h) - (S(e.top - k) <= h)), f || g || (f = (h >= l - j) - (h >= j), g = (h >= m - k) - (h >= k), (f || g) && (d = M)), (J.vx !== f || J.vy !== g || J.el !== d) && (J.el = d, J.vx = f, J.vy = g, clearInterval(J.pid), d && (J.pid = setInterval(function() {
                        d === M ? M.scrollTo(M.pageXOffset + f * i, M.pageYOffset + g * i) : (g && (d.scrollTop += g * i), f && (d.scrollLeft += f * i))
                    }, 24)))
                }
            }, 30),
            V = function(a) {
                var b = a.group;
                b && "object" == typeof b || (b = a.group = {
                    name: b
                }), ["pull", "put"].forEach(function(a) {
                    a in b || (b[a] = !0)
                }), a.groups = " " + b.name + (b.put.join ? " " + b.put.join(" ") : "") + " "
            };
        return a.prototype = {
            constructor: a,
            _onTapStart: function(a) {
                var b = this,
                    d = this.el,
                    e = this.options,
                    f = a.type,
                    g = a.touches && a.touches[0],
                    h = (g || a).target,
                    i = h,
                    k = e.filter;
                if (!("mousedown" === f && 0 !== a.button || e.disabled) && (h = c(h, e.draggable, d))) {
                    if (D = p(h), "function" == typeof k) {
                        if (k.call(this, a, h, this)) return j(b, i, "filter", h, d, D), void a.preventDefault()
                    } else if (k && (k = k.split(",").some(function(a) {
                            return a = c(i, a.trim(), d), a ? (j(b, a, "filter", h, d, D), !0) : void 0
                        }))) return void a.preventDefault();
                    (!e.handle || c(i, e.handle, d)) && this._prepareDragStart(a, g, h)
                }
            },
            _prepareDragStart: function(a, b, c) {
                var d, f = this,
                    h = f.el,
                    j = f.options,
                    k = h.ownerDocument;
                c && !s && c.parentNode === h && (G = a, w = h, s = c, t = s.parentNode, x = s.nextSibling, F = j.group, d = function() {
                    f._disableDelayedDrag(), s.draggable = !0, g(s, f.options.chosenClass, !0), f._triggerDragStart(b)
                }, j.ignore.split(",").forEach(function(a) {
                    i(s, a.trim(), l)
                }), e(k, "mouseup", f._onDrop), e(k, "touchend", f._onDrop), e(k, "touchcancel", f._onDrop), j.delay ? (e(k, "mouseup", f._disableDelayedDrag), e(k, "touchend", f._disableDelayedDrag), e(k, "touchcancel", f._disableDelayedDrag), e(k, "mousemove", f._disableDelayedDrag), e(k, "touchmove", f._disableDelayedDrag), f._dragStartTimer = setTimeout(d, j.delay)) : d())
            },
            _disableDelayedDrag: function() {
                var a = this.el.ownerDocument;
                clearTimeout(this._dragStartTimer), f(a, "mouseup", this._disableDelayedDrag), f(a, "touchend", this._disableDelayedDrag), f(a, "touchcancel", this._disableDelayedDrag), f(a, "mousemove", this._disableDelayedDrag), f(a, "touchmove", this._disableDelayedDrag)
            },
            _triggerDragStart: function(a) {
                a ? (G = {
                    target: s,
                    clientX: a.clientX,
                    clientY: a.clientY
                }, this._onDragStart(G, "touch")) : this.nativeDraggable ? (e(s, "dragend", this), e(w, "dragstart", this._onDragStart)) : this._onDragStart(G, !0);
                try {
                    N.selection ? N.selection.empty() : window.getSelection().removeAllRanges()
                } catch (b) {}
            },
            _dragStarted: function() {
                w && s && (g(s, this.options.ghostClass, !0), a.active = this, j(this, w, "start", s, w, D))
            },
            _emulateDragOver: function() {
                if (H) {
                    if (this._lastX === H.clientX && this._lastY === H.clientY) return;
                    this._lastX = H.clientX, this._lastY = H.clientY, Q || h(u, "display", "none");
                    var a = N.elementFromPoint(H.clientX, H.clientY),
                        b = a,
                        c = " " + this.options.group.name,
                        d = T.length;
                    if (b)
                        do {
                            if (b[L] && b[L].options.groups.indexOf(c) > -1) {
                                for (; d--;) T[d]({
                                    clientX: H.clientX,
                                    clientY: H.clientY,
                                    target: a,
                                    rootEl: b
                                });
                                break
                            }
                            a = b
                        } while (b = b.parentNode);
                    Q || h(u, "display", "")
                }
            },
            _onTouchMove: function(b) {
                if (G) {
                    a.active || this._dragStarted(), this._appendGhost();
                    var c = b.touches ? b.touches[0] : b,
                        d = c.clientX - G.clientX,
                        e = c.clientY - G.clientY,
                        f = b.touches ? "translate3d(" + d + "px," + e + "px,0)" : "translate(" + d + "px," + e + "px)";
                    I = !0, H = c, h(u, "webkitTransform", f), h(u, "mozTransform", f), h(u, "msTransform", f), h(u, "transform", f), b.preventDefault()
                }
            },
            _appendGhost: function() {
                if (!u) {
                    var a, b = s.getBoundingClientRect(),
                        c = h(s),
                        d = this.options;
                    u = s.cloneNode(!0), g(u, d.ghostClass, !1), g(u, d.fallbackClass, !0), h(u, "top", b.top - O(c.marginTop, 10)), h(u, "left", b.left - O(c.marginLeft, 10)), h(u, "width", b.width), h(u, "height", b.height), h(u, "opacity", "0.8"), h(u, "position", "fixed"), h(u, "zIndex", "100000"), h(u, "pointerEvents", "none"), d.fallbackOnBody && N.body.appendChild(u) || w.appendChild(u), a = u.getBoundingClientRect(), h(u, "width", 2 * b.width - a.width), h(u, "height", 2 * b.height - a.height)
                }
            },
            _onDragStart: function(a, b) {
                var c = a.dataTransfer,
                    d = this.options;
                this._offUpEvents(), "clone" == F.pull && (v = s.cloneNode(!0), h(v, "display", "none"), w.insertBefore(v, s)), b ? ("touch" === b ? (e(N, "touchmove", this._onTouchMove), e(N, "touchend", this._onDrop), e(N, "touchcancel", this._onDrop)) : (e(N, "mousemove", this._onTouchMove), e(N, "mouseup", this._onDrop)), this._loopId = setInterval(this._emulateDragOver, 50)) : (c && (c.effectAllowed = "move", d.setData && d.setData.call(this, c, s)), e(N, "drop", this), setTimeout(this._dragStarted, 0))
            },
            _onDragOver: function(a) {
                var d, e, f, g = this.el,
                    i = this.options,
                    j = i.group,
                    l = j.put,
                    o = F === j,
                    p = i.sort;
                if (void 0 !== a.preventDefault && (a.preventDefault(), !i.dragoverBubble && a.stopPropagation()), I = !0, F && !i.disabled && (o ? p || (f = !w.contains(s)) : F.pull && l && (F.name === j.name || l.indexOf && ~l.indexOf(F.name))) && (void 0 === a.rootEl || a.rootEl === this.el)) {
                    if (U(a, i, this.el), R) return;
                    if (d = c(a.target, i.draggable, g), e = s.getBoundingClientRect(), f) return b(!0), void(v || x ? w.insertBefore(s, v || x) : p || w.appendChild(s));
                    if (0 === g.children.length || g.children[0] === u || g === a.target && (d = n(g, a))) {
                        if (d) {
                            if (d.animated) return;
                            r = d.getBoundingClientRect()
                        }
                        b(o), k(w, g, s, e, d, r) !== !1 && (s.contains(g) || (g.appendChild(s), t = g), this._animate(e, s), d && this._animate(r, d))
                    } else if (d && !d.animated && d !== s && void 0 !== d.parentNode[L]) {
                        A !== d && (A = d, B = h(d), C = h(d.parentNode));
                        var q, r = d.getBoundingClientRect(),
                            y = r.right - r.left,
                            z = r.bottom - r.top,
                            D = /left|right|inline/.test(B.cssFloat + B.display) || "flex" == C.display && 0 === C["flex-direction"].indexOf("row"),
                            E = d.offsetWidth > s.offsetWidth,
                            G = d.offsetHeight > s.offsetHeight,
                            H = (D ? (a.clientX - r.left) / y : (a.clientY - r.top) / z) > .5,
                            J = d.nextElementSibling,
                            K = k(w, g, s, e, d, r);
                        if (K !== !1) {
                            if (R = !0, setTimeout(m, 30), b(o), 1 === K || -1 === K) q = 1 === K;
                            else if (D) {
                                var M = s.offsetTop,
                                    N = d.offsetTop;
                                q = M === N ? d.previousElementSibling === s && !E || H && E : N > M
                            } else q = J !== s && !G || H && G;
                            s.contains(g) || (q && !J ? g.appendChild(s) : d.parentNode.insertBefore(s, q ? J : d)), t = s.parentNode, this._animate(e, s), this._animate(r, d)
                        }
                    }
                }
            },
            _animate: function(a, b) {
                var c = this.options.animation;
                if (c) {
                    var d = b.getBoundingClientRect();
                    h(b, "transition", "none"), h(b, "transform", "translate3d(" + (a.left - d.left) + "px," + (a.top - d.top) + "px,0)"), b.offsetWidth, h(b, "transition", "all " + c + "ms"), h(b, "transform", "translate3d(0,0,0)"), clearTimeout(b.animated), b.animated = setTimeout(function() {
                        h(b, "transition", ""), h(b, "transform", ""), b.animated = !1
                    }, c)
                }
            },
            _offUpEvents: function() {
                var a = this.el.ownerDocument;
                f(N, "touchmove", this._onTouchMove), f(a, "mouseup", this._onDrop), f(a, "touchend", this._onDrop), f(a, "touchcancel", this._onDrop)
            },
            _onDrop: function(b) {
                var c = this.el,
                    d = this.options;
                clearInterval(this._loopId), clearInterval(J.pid), clearTimeout(this._dragStartTimer), f(N, "mousemove", this._onTouchMove), this.nativeDraggable && (f(N, "drop", this), f(c, "dragstart", this._onDragStart)), this._offUpEvents(), b && (I && (b.preventDefault(), !d.dropBubble && b.stopPropagation()), u && u.parentNode.removeChild(u), s && (this.nativeDraggable && f(s, "dragend", this), l(s), g(s, this.options.ghostClass, !1), g(s, this.options.chosenClass, !1), w !== t ? (E = p(s), E >= 0 && (j(null, t, "sort", s, w, D, E), j(this, w, "sort", s, w, D, E), j(null, t, "add", s, w, D, E), j(this, w, "remove", s, w, D, E))) : (v && v.parentNode.removeChild(v), s.nextSibling !== x && (E = p(s), E >= 0 && (j(this, w, "update", s, w, D, E), j(this, w, "sort", s, w, D, E)))), a.active && ((null === E || -1 === E) && (E = D), j(this, w, "end", s, w, D, E), this.save())), w = s = t = u = x = v = y = z = G = H = I = E = A = B = F = a.active = null)
            },
            handleEvent: function(a) {
                var b = a.type;
                "dragover" === b || "dragenter" === b ? s && (this._onDragOver(a), d(a)) : ("drop" === b || "dragend" === b) && this._onDrop(a)
            },
            toArray: function() {
                for (var a, b = [], d = this.el.children, e = 0, f = d.length, g = this.options; f > e; e++) a = d[e], c(a, g.draggable, this.el) && b.push(a.getAttribute(g.dataIdAttr) || o(a));
                return b
            },
            sort: function(a) {
                var b = {},
                    d = this.el;
                this.toArray().forEach(function(a, e) {
                    var f = d.children[e];
                    c(f, this.options.draggable, d) && (b[a] = f)
                }, this), a.forEach(function(a) {
                    b[a] && (d.removeChild(b[a]), d.appendChild(b[a]))
                })
            },
            save: function() {
                var a = this.options.store;
                a && a.set(this)
            },
            closest: function(a, b) {
                return c(a, b || this.options.draggable, this.el)
            },
            option: function(a, b) {
                var c = this.options;
                return void 0 === b ? c[a] : (c[a] = b, void("group" === a && V(c)))
            },
            destroy: function() {
                var a = this.el;
                a[L] = null, f(a, "mousedown", this._onTapStart), f(a, "touchstart", this._onTapStart), this.nativeDraggable && (f(a, "dragover", this), f(a, "dragenter", this)), Array.prototype.forEach.call(a.querySelectorAll("[draggable]"), function(a) {
                    a.removeAttribute("draggable")
                }), T.splice(T.indexOf(this._onDragOver), 1), this._onDrop(), this.el = a = null
            }
        }, a.utils = {
            on: e,
            off: f,
            css: h,
            find: i,
            is: function(a, b) {
                return !!c(a, b, a)
            },
            extend: r,
            throttle: q,
            closest: c,
            toggleClass: g,
            index: p
        }, a.create = function(b, c) {
            return new a(b, c)
        }, a.version = "1.4.2", a
    });
    /*! RESOURCE: /scripts/libs/lodash.min.js */
    /**
     * @license
     * lodash 4.11.0 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
     * Build: `lodash -o ./dist/lodash.js`
     */
    ;
    (function() {
        function t(t, n) {
            return t.set(n[0], n[1]), t
        }
    
        function n(t, n) {
            return t.add(n), t
        }
    
        function r(t, n, r) {
            switch (r.length) {
                case 0:
                    return t.call(n);
                case 1:
                    return t.call(n, r[0]);
                case 2:
                    return t.call(n, r[0], r[1]);
                case 3:
                    return t.call(n, r[0], r[1], r[2])
            }
            return t.apply(n, r)
        }
    
        function e(t, n, r, e) {
            for (var u = -1, o = t.length; ++u < o;) {
                var i = t[u];
                n(e, i, r(i), t)
            }
            return e
        }
    
        function u(t, n) {
            for (var r = -1, e = t.length; ++r < e && false !== n(t[r], r, t););
            return t
        }
    
        function o(t, n) {
            for (var r = -1, e = t.length; ++r < e;)
                if (!n(t[r], r, t)) return false;
            return true
        }
    
        function i(t, n) {
            for (var r = -1, e = t.length, u = 0, o = []; ++r < e;) {
                var i = t[r];
                n(i, r, t) && (o[u++] = i)
            }
            return o
        }
    
        function f(t, n) {
            return !!t.length && -1 < d(t, n, 0)
        }
    
        function c(t, n, r) {
            for (var e = -1, u = t.length; ++e < u;)
                if (r(n, t[e])) return true;
            return false
        }
    
        function a(t, n) {
            for (var r = -1, e = t.length, u = Array(e); ++r < e;) u[r] = n(t[r], r, t);
            return u
        }
    
        function l(t, n) {
            for (var r = -1, e = n.length, u = t.length; ++r < e;) t[u + r] = n[r];
            return t
        }
    
        function s(t, n, r, e) {
            var u = -1,
                o = t.length;
            for (e && o && (r = t[++u]); ++u < o;) r = n(r, t[u], u, t);
            return r
        }
    
        function h(t, n, r, e) {
            var u = t.length;
            for (e && u && (r = t[--u]); u--;) r = n(r, t[u], u, t);
            return r
        }
    
        function p(t, n) {
            for (var r = -1, e = t.length; ++r < e;)
                if (n(t[r], r, t)) return true;
            return false
        }
    
        function _(t, n, r) {
            for (var e = -1, u = t.length; ++e < u;) {
                var o = t[e],
                    i = n(o);
                if (null != i && (f === q ? i === i : r(i, f))) var f = i,
                    c = o
            }
            return c
        }
    
        function v(t, n, r, e) {
            var u;
            return r(t, function(t, r, o) {
                return n(t, r, o) ? (u = e ? r : t, false) : void 0
            }), u
        }
    
        function g(t, n, r) {
            for (var e = t.length, u = r ? e : -1; r ? u-- : ++u < e;)
                if (n(t[u], u, t)) return u;
            return -1
        }
    
        function d(t, n, r) {
            if (n !== n) return M(t, r);
            --r;
            for (var e = t.length; ++r < e;)
                if (t[r] === n) return r;
            return -1
        }
    
        function y(t, n, r, e) {
            --r;
            for (var u = t.length; ++r < u;)
                if (e(t[r], n)) return r;
            return -1
        }
    
        function b(t, n) {
            var r = t ? t.length : 0;
            return r ? m(t, n) / r : K
        }
    
        function x(t, n, r, e, u) {
            return u(t, function(t, u, o) {
                r = e ? (e = false, t) : n(r, t, u, o)
            }), r
        }
    
        function j(t, n) {
            var r = t.length;
            for (t.sort(n); r--;) t[r] = t[r].c;
            return t
        }
    
        function m(t, n) {
            for (var r, e = -1, u = t.length; ++e < u;) {
                var o = n(t[e]);
                o !== q && (r = r === q ? o : r + o)
            }
            return r
        }
    
        function w(t, n) {
            for (var r = -1, e = Array(t); ++r < t;) e[r] = n(r);
            return e
        }
    
        function A(t, n) {
            return a(n, function(n) {
                return [n, t[n]];
            })
        }
    
        function O(t) {
            return function(n) {
                return t(n)
            }
        }
    
        function k(t, n) {
            return a(n, function(n) {
                return t[n]
            })
        }
    
        function E(t, n) {
            for (var r = -1, e = t.length; ++r < e && -1 < d(n, t[r], 0););
            return r
        }
    
        function I(t, n) {
            for (var r = t.length; r-- && -1 < d(n, t[r], 0););
            return r
        }
    
        function S(t) {
            return t && t.Object === Object ? t : null
        }
    
        function R(t, n) {
            if (t !== n) {
                var r = null === t,
                    e = t === q,
                    u = t === t,
                    o = null === n,
                    i = n === q,
                    f = n === n;
                if (t > n && !o || !u || r && !i && f || e && f) return 1;
                if (n > t && !r || !f || o && !e && u || i && u) return -1
            }
            return 0
        }
    
        function W(t) {
            return function(n, r) {
                var e;
                return n === q && r === q ? 0 : (n !== q && (e = n), r !== q && (e = e === q ? r : t(e, r)), e)
            }
        }
    
        function B(t) {
            return Ut[t]
        }
    
        function L(t) {
            return Dt[t]
        }
    
        function C(t) {
            return "\\" + Nt[t]
        }
    
        function M(t, n, r) {
            var e = t.length;
            for (n += r ? 0 : -1; r ? n-- : ++n < e;) {
                var u = t[n];
                if (u !== u) return n
            }
            return -1
        }
    
        function z(t) {
            var n = false;
            if (null != t && typeof t.toString != "function") try {
                n = !!(t + "")
            } catch (r) {}
            return n
        }
    
        function U(t, n) {
            return t = typeof t == "number" || jt.test(t) ? +t : -1, t > -1 && 0 == t % 1 && (null == n ? 9007199254740991 : n) > t
        }
    
        function D(t) {
            for (var n, r = []; !(n = t.next()).done;) r.push(n.value);
            return r
        }
    
        function $(t) {
            var n = -1,
                r = Array(t.size);
            return t.forEach(function(t, e) {
                r[++n] = [e, t]
            }), r
        }
    
        function F(t, n) {
            for (var r = -1, e = t.length, u = 0, o = []; ++r < e;) {
                var i = t[r];
                i !== n && "__lodash_placeholder__" !== i || (t[r] = "__lodash_placeholder__", o[u++] = r)
            }
            return o
        }
    
        function N(t) {
            var n = -1,
                r = Array(t.size);
            return t.forEach(function(t) {
                r[++n] = t
            }), r
        }
    
        function P(t) {
            if (!t || !Bt.test(t)) return t.length;
            for (var n = Rt.lastIndex = 0; Rt.test(t);) n++;
            return n
        }
    
        function Z(t) {
            return $t[t]
        }
    
        function T(S) {
            function jt(t) {
                if (Le(t) && !oi(t) && !(t instanceof Et)) {
                    if (t instanceof kt) return t;
                    if (xu.call(t, "__wrapped__")) return Xr(t)
                }
                return new kt(t)
            }
    
            function Ot() {}
    
            function kt(t, n) {
                this.__wrapped__ = t, this.__actions__ = [], this.__chain__ = !!n, this.__index__ = 0, this.__values__ = q
            }
    
            function Et(t) {
                this.__wrapped__ = t, this.__actions__ = [], this.__dir__ = 1, this.__filtered__ = false, this.__iteratees__ = [], this.__takeCount__ = 4294967295, this.__views__ = []
            }
    
            function Ut() {}
    
            function Dt(t) {
                var n = -1,
                    r = t ? t.length : 0;
                for (this.clear(); ++n < r;) {
                    var e = t[n];
                    this.set(e[0], e[1])
                }
            }
    
            function $t(t) {
                var n = -1,
                    r = t ? t.length : 0;
                for (this.__data__ = new Dt; ++n < r;) this.push(t[n])
            }
    
            function Ft(t, n) {
                var r = t.__data__;
                return qr(n) ? (r = r.__data__, "__lodash_hash_undefined__" === (typeof n == "string" ? r.string : r.hash)[n]) : r.has(n)
            }
    
            function Nt(t) {
                var n = -1,
                    r = t ? t.length : 0;
                for (this.clear(); ++n < r;) {
                    var e = t[n];
                    this.set(e[0], e[1])
                }
            }
    
            function Tt(t, n) {
                var r = Kt(t, n);
                return 0 > r ? false : (r == t.length - 1 ? t.pop() : Uu.call(t, r, 1), true)
            }
    
            function qt(t, n) {
                var r = Kt(t, n);
                return 0 > r ? q : t[r][1]
            }
    
            function Kt(t, n) {
                for (var r = t.length; r--;)
                    if (we(t[r][0], n)) return r;
                return -1
            }
    
            function Gt(t, n, r) {
                var e = Kt(t, n);
                0 > e ? t.push([n, r]) : t[e][1] = r
            }
    
            function Jt(t, n, r, e) {
                return t === q || we(t, du[r]) && !xu.call(e, r) ? n : t
            }
    
            function Qt(t, n, r) {
                (r === q || we(t[n], r)) && (typeof n != "number" || r !== q || n in t) || (t[n] = r)
            }
    
            function Xt(t, n, r) {
                var e = t[n];
                xu.call(t, n) && we(e, r) && (r !== q || n in t) || (t[n] = r)
            }
    
            function tn(t, n, r, e) {
                return _o(t, function(t, u, o) {
                    n(e, t, r(t), o)
                }), e
            }
    
            function nn(t, n) {
                return t && ir(n, He(n), t)
            }
    
            function rn(t, n) {
                for (var r = -1, e = null == t, u = n.length, o = Array(u); ++r < u;) o[r] = e ? q : Ge(t, n[r]);
                return o
            }
    
            function en(t, n, r) {
                return t === t && (r !== q && (t = t > r ? r : t),
                    n !== q && (t = n > t ? n : t)), t
            }
    
            function un(t, n, r, e, o, i, f) {
                var c;
                if (e && (c = i ? e(t, o, i, f) : e(t)), c !== q) return c;
                if (!Be(t)) return t;
                if (o = oi(t)) {
                    if (c = Ur(t), !n) return or(t, c)
                } else {
                    var a = Mr(t),
                        l = "[object Function]" == a || "[object GeneratorFunction]" == a;
                    if (ii(t)) return nr(t, n);
                    if ("[object Object]" == a || "[object Arguments]" == a || l && !i) {
                        if (z(t)) return i ? t : {};
                        if (c = Dr(l ? {} : t), !n) return fr(t, nn(c, t))
                    } else {
                        if (!zt[a]) return i ? t : {};
                        c = $r(t, a, un, n)
                    }
                }
                if (f || (f = new Nt), i = f.get(t)) return i;
                if (f.set(t, c), !o) var s = r ? dn(t, He, Cr) : He(t);
                return u(s || t, function(u, o) {
                    s && (o = u, u = t[o]), Xt(c, o, un(u, n, r, e, o, t, f))
                }), c
            }
    
            function on(t) {
                var n = He(t),
                    r = n.length;
                return function(e) {
                    if (null == e) return !r;
                    for (var u = r; u--;) {
                        var o = n[u],
                            i = t[o],
                            f = e[o];
                        if (f === q && !(o in Object(e)) || !i(f)) return false
                    }
                    return true
                }
            }
    
            function fn(t) {
                return Be(t) ? Cu(t) : {}
            }
    
            function cn(t, n, r) {
                if (typeof t != "function") throw new vu("Expected a function");
                return zu(function() {
                    t.apply(q, r)
                }, n)
            }
    
            function an(t, n, r, e) {
                var u = -1,
                    o = f,
                    i = true,
                    l = t.length,
                    s = [],
                    h = n.length;
                if (!l) return s;
                r && (n = a(n, O(r))), e ? (o = c, i = false) : n.length >= 200 && (o = Ft,
                    i = false, n = new $t(n));
                t: for (; ++u < l;) {
                    var p = t[u],
                        _ = r ? r(p) : p;
                    if (i && _ === _) {
                        for (var v = h; v--;)
                            if (n[v] === _) continue t;
                        s.push(p)
                    } else o(n, _, e) || s.push(p)
                }
                return s
            }
    
            function ln(t, n) {
                var r = true;
                return _o(t, function(t, e, u) {
                    return r = !!n(t, e, u)
                }), r
            }
    
            function sn(t, n) {
                var r = [];
                return _o(t, function(t, e, u) {
                    n(t, e, u) && r.push(t)
                }), r
            }
    
            function hn(t, n, r, e, u) {
                var o = -1,
                    i = t.length;
                for (r || (r = Nr), u || (u = []); ++o < i;) {
                    var f = t[o];
                    n > 0 && r(f) ? n > 1 ? hn(f, n - 1, r, e, u) : l(u, f) : e || (u[u.length] = f)
                }
                return u
            }
    
            function pn(t, n) {
                return t && go(t, n, He)
            }
    
            function _n(t, n) {
                return t && yo(t, n, He)
            }
    
            function vn(t, n) {
                return i(n, function(n) {
                    return Se(t[n])
                })
            }
    
            function gn(t, n) {
                n = Tr(n, t) ? [n] : Xn(n);
                for (var r = 0, e = n.length; null != t && e > r;) t = t[n[r++]];
                return r && r == e ? t : q
            }
    
            function dn(t, n, r) {
                return n = n(t), oi(t) ? n : l(n, r(t))
            }
    
            function yn(t, n) {
                return xu.call(t, n) || typeof t == "object" && n in t && null === Fu(Object(t))
            }
    
            function bn(t, n) {
                return n in Object(t)
            }
    
            function xn(t, n, r) {
                for (var e = r ? c : f, u = t[0].length, o = t.length, i = o, l = Array(o), s = 1 / 0, h = []; i--;) {
                    var p = t[i];
                    i && n && (p = a(p, O(n))), s = qu(p.length, s),
                        l[i] = r || !n && (120 > u || 120 > p.length) ? q : new $t(i && p)
                }
                var p = t[0],
                    _ = -1,
                    v = l[0];
                t: for (; ++_ < u && s > h.length;) {
                    var g = p[_],
                        d = n ? n(g) : g;
                    if (v ? !Ft(v, d) : !e(h, d, r)) {
                        for (i = o; --i;) {
                            var y = l[i];
                            if (y ? !Ft(y, d) : !e(t[i], d, r)) continue t
                        }
                        v && v.push(d), h.push(g)
                    }
                }
                return h
            }
    
            function jn(t, n, r) {
                var e = {};
                return pn(t, function(t, u, o) {
                    n(e, r(t), u, o)
                }), e
            }
    
            function mn(t, n, e) {
                return Tr(n, t) || (n = Xn(n), t = Yr(t, n), n = ee(n)), n = null == t ? t : t[n], null == n ? q : r(n, t, e)
            }
    
            function wn(t, n, r, e, u) {
                if (t === n) n = true;
                else if (null == t || null == n || !Be(t) && !Le(n)) n = t !== t && n !== n;
                else t: {
                    var o = oi(t),
                        i = oi(n),
                        f = "[object Array]",
                        c = "[object Array]";o || (f = Mr(t), f = "[object Arguments]" == f ? "[object Object]" : f),
                    i || (c = Mr(n), c = "[object Arguments]" == c ? "[object Object]" : c);
                    var a = "[object Object]" == f && !z(t),
                        i = "[object Object]" == c && !z(n);
                    if ((c = f == c) && !a) u || (u = new Nt),
                    n = o || Fe(t) ? Er(t, n, wn, r, e, u) : Ir(t, n, f, wn, r, e, u);
                    else {
                        if (!(2 & e) && (o = a && xu.call(t, "__wrapped__"), f = i && xu.call(n, "__wrapped__"), o || f)) {
                            t = o ? t.value() : t, n = f ? n.value() : n, u || (u = new Nt), n = wn(t, n, r, e, u);
                            break t
                        }
                        if (c) n: if (u || (u = new Nt), o = 2 & e,
                            f = He(t), i = f.length, c = He(n).length, i == c || o) {
                            for (a = i; a--;) {
                                var l = f[a];
                                if (!(o ? l in n : yn(n, l))) {
                                    n = false;
                                    break n
                                }
                            }
                            if (c = u.get(t)) n = c == n;
                            else {
                                c = true, u.set(t, n);
                                for (var s = o; ++a < i;) {
                                    var l = f[a],
                                        h = t[l],
                                        p = n[l];
                                    if (r) var _ = o ? r(p, h, l, n, t, u) : r(h, p, l, t, n, u);
                                    if (_ === q ? h !== p && !wn(h, p, r, e, u) : !_) {
                                        c = false;
                                        break
                                    }
                                    s || (s = "constructor" == l)
                                }
                                c && !s && (r = t.constructor, e = n.constructor, r != e && "constructor" in t && "constructor" in n && !(typeof r == "function" && r instanceof r && typeof e == "function" && e instanceof e) && (c = false)), u["delete"](t), n = c
                            }
                        } else n = false;
                        else n = false;
                    }
                }
                return n
            }
    
            function An(t, n, r, e) {
                var u = r.length,
                    o = u,
                    i = !e;
                if (null == t) return !o;
                for (t = Object(t); u--;) {
                    var f = r[u];
                    if (i && f[2] ? f[1] !== t[f[0]] : !(f[0] in t)) return false
                }
                for (; ++u < o;) {
                    var f = r[u],
                        c = f[0],
                        a = t[c],
                        l = f[1];
                    if (i && f[2]) {
                        if (a === q && !(c in t)) return false
                    } else {
                        if (f = new Nt, e) var s = e(a, l, c, t, n, f);
                        if (s === q ? !wn(l, a, e, 3, f) : !s) return false
                    }
                }
                return true
            }
    
            function On(t) {
                return typeof t == "function" ? t : null == t ? iu : typeof t == "object" ? oi(t) ? Sn(t[0], t[1]) : In(t) : lu(t)
            }
    
            function kn(t) {
                t = null == t ? t : Object(t);
                var n, r = [];
                for (n in t) r.push(n);
                return r
            }
    
            function En(t, n) {
                var r = -1,
                    e = ke(t) ? Array(t.length) : [];
                return _o(t, function(t, u, o) {
                    e[++r] = n(t, u, o)
                }), e
            }
    
            function In(t) {
                var n = Wr(t);
                return 1 == n.length && n[0][2] ? Gr(n[0][0], n[0][1]) : function(r) {
                    return r === t || An(r, t, n)
                }
            }
    
            function Sn(t, n) {
                return Tr(t) && n === n && !Be(n) ? Gr(t, n) : function(r) {
                    var e = Ge(r, t);
                    return e === q && e === n ? Ye(r, t) : wn(n, e, q, 3)
                }
            }
    
            function Rn(t, n, r, e, o) {
                if (t !== n) {
                    if (!oi(n) && !Fe(n)) var i = Qe(n);
                    u(i || n, function(u, f) {
                        if (i && (f = u, u = n[f]), Be(u)) {
                            o || (o = new Nt);
                            var c = f,
                                a = o,
                                l = t[c],
                                s = n[c],
                                h = a.get(s);
                            if (h) Qt(t, c, h);
                            else {
                                var h = e ? e(l, s, c + "", t, n, a) : q,
                                    p = h === q;
                                p && (h = s, oi(s) || Fe(s) ? oi(l) ? h = l : Ee(l) ? h = or(l) : (p = false, h = un(s, true)) : ze(s) || Oe(s) ? Oe(l) ? h = Ve(l) : !Be(l) || r && Se(l) ? (p = false, h = un(s, true)) : h = l : p = false), a.set(s, h), p && Rn(h, s, r, e, a), a["delete"](s), Qt(t, c, h)
                            }
                        } else c = e ? e(t[f], u, f + "", t, n, o) : q, c === q && (c = u), Qt(t, f, c)
                    })
                }
            }
    
            function Wn(t, n) {
                var r = t.length;
                return r ? (n += 0 > n ? r : 0, U(n, r) ? t[n] : q) : void 0
            }
    
            function Bn(t, n, r) {
                var e = -1;
                return n = a(n.length ? n : [iu], O(Rr())), t = En(t, function(t) {
                    return {
                        a: a(n, function(n) {
                            return n(t)
                        }),
                        b: ++e,
                        c: t
                    }
                }), j(t, function(t, n) {
                    var e;
                    t: {
                        e = -1;
                        for (var u = t.a, o = n.a, i = u.length, f = r.length; ++e < i;) {
                            var c = R(u[e], o[e]);
                            if (c) {
                                e = f > e ? c * ("desc" == r[e] ? -1 : 1) : c;
                                break t
                            }
                        }
                        e = t.b - n.b
                    }
                    return e
                })
            }
    
            function Ln(t, n) {
                return t = Object(t), s(n, function(n, r) {
                    return r in t && (n[r] = t[r]), n
                }, {})
            }
    
            function Cn(t, n) {
                for (var r = -1, e = dn(t, Qe, wo), u = e.length, o = {}; ++r < u;) {
                    var i = e[r],
                        f = t[i];
                    n(f, i) && (o[i] = f)
                }
                return o
            }
    
            function Mn(t) {
                return function(n) {
                    return null == n ? q : n[t]
                }
            }
    
            function zn(t) {
                return function(n) {
                    return gn(n, t)
                }
            }
    
            function Un(t, n, r, e) {
                var u = e ? y : d,
                    o = -1,
                    i = n.length,
                    f = t;
                for (r && (f = a(t, O(r))); ++o < i;)
                    for (var c = 0, l = n[o], l = r ? r(l) : l; - 1 < (c = u(f, l, c, e));) f !== t && Uu.call(f, c, 1), Uu.call(t, c, 1);
                return t
            }
    
            function Dn(t, n) {
                for (var r = t ? n.length : 0, e = r - 1; r--;) {
                    var u = n[r];
                    if (e == r || u != o) {
                        var o = u;
                        if (U(u)) Uu.call(t, u, 1);
                        else if (Tr(u, t)) delete t[u];
                        else {
                            var u = Xn(u),
                                i = Yr(t, u);
                            null != i && delete i[ee(u)]
                        }
                    }
                }
            }
    
            function $n(t, n) {
                return t + $u(Ku() * (n - t + 1))
            }
    
            function Fn(t, n) {
                var r = "";
                if (!t || 1 > n || n > 9007199254740991) return r;
                do n % 2 && (r += t), (n = $u(n / 2)) && (t += t); while (n);
                return r;
            }
    
            function Nn(t, n, r, e) {
                n = Tr(n, t) ? [n] : Xn(n);
                for (var u = -1, o = n.length, i = o - 1, f = t; null != f && ++u < o;) {
                    var c = n[u];
                    if (Be(f)) {
                        var a = r;
                        if (u != i) {
                            var l = f[c],
                                a = e ? e(l, c, f) : q;
                            a === q && (a = null == l ? U(n[u + 1]) ? [] : {} : l)
                        }
                        Xt(f, c, a)
                    }
                    f = f[c]
                }
                return t
            }
    
            function Pn(t, n, r) {
                var e = -1,
                    u = t.length;
                for (0 > n && (n = -n > u ? 0 : u + n), r = r > u ? u : r, 0 > r && (r += u), u = n > r ? 0 : r - n >>> 0, n >>>= 0, r = Array(u); ++e < u;) r[e] = t[e + n];
                return r
            }
    
            function Zn(t, n) {
                var r;
                return _o(t, function(t, e, u) {
                    return r = n(t, e, u), !r
                }), !!r
            }
    
            function Tn(t, n, r) {
                var e = 0,
                    u = t ? t.length : e;
                if (typeof n == "number" && n === n && 2147483647 >= u) {
                    for (; u > e;) {
                        var o = e + u >>> 1,
                            i = t[o];
                        (r ? n >= i : n > i) && null !== i ? e = o + 1 : u = o
                    }
                    return u
                }
                return qn(t, n, iu, r)
            }
    
            function qn(t, n, r, e) {
                n = r(n);
                for (var u = 0, o = t ? t.length : 0, i = n !== n, f = null === n, c = n === q; o > u;) {
                    var a = $u((u + o) / 2),
                        l = r(t[a]),
                        s = l !== q,
                        h = l === l;
                    (i ? h || e : f ? h && s && (e || null != l) : c ? h && (e || s) : null == l ? 0 : e ? n >= l : n > l) ? u = a + 1: o = a
                }
                return qu(o, 4294967294)
            }
    
            function Vn(t, n) {
                for (var r = 0, e = t.length, u = t[0], o = n ? n(u) : u, i = o, f = 1, c = [u]; ++r < e;) u = t[r], o = n ? n(u) : u, we(o, i) || (i = o, c[f++] = u);
                return c
            }
    
            function Kn(t, n, r) {
                var e = -1,
                    u = f,
                    o = t.length,
                    i = true,
                    a = [],
                    l = a;
                if (r) i = false, u = c;
                else if (o < 200) l = n ? [] : a;
                else {
                    if (u = n ? null : xo(t)) return N(u);
                    i = false, u = Ft, l = new $t
                }
                t: for (; ++e < o;) {
                    var s = t[e],
                        h = n ? n(s) : s;
                    if (i && h === h) {
                        for (var p = l.length; p--;)
                            if (l[p] === h) continue t;
                        n && l.push(h), a.push(s)
                    } else u(l, h, r) || (l !== a && l.push(h), a.push(s))
                }
                return a
            }
    
            function Gn(t, n, r, e) {
                for (var u = t.length, o = e ? u : -1;
                    (e ? o-- : ++o < u) && n(t[o], o, t););
                return r ? Pn(t, e ? 0 : o, e ? o + 1 : u) : Pn(t, e ? o + 1 : 0, e ? u : o)
            }
    
            function Jn(t, n) {
                var r = t;
                return r instanceof Et && (r = r.value()), s(n, function(t, n) {
                    return n.func.apply(n.thisArg, l([t], n.args));
                }, r)
            }
    
            function Yn(t, n, r) {
                for (var e = -1, u = t.length; ++e < u;) var o = o ? l(an(o, t[e], n, r), an(t[e], o, n, r)) : t[e];
                return o && o.length ? Kn(o, n, r) : []
            }
    
            function Hn(t, n, r) {
                for (var e = -1, u = t.length, o = n.length, i = {}; ++e < u;) r(i, t[e], o > e ? n[e] : q);
                return i
            }
    
            function Qn(t) {
                return Ee(t) ? t : []
            }
    
            function Xn(t) {
                return oi(t) ? t : Oo(t)
            }
    
            function tr(t, n, r) {
                var e = t.length;
                return r = r === q ? e : r, n || e > r ? Pn(t, n, r) : t
            }
    
            function nr(t, n) {
                if (n) return t.slice();
                var r = new t.constructor(t.length);
                return t.copy(r), r
            }
    
            function rr(t) {
                var n = new t.constructor(t.byteLength);
                return new Su(n).set(new Su(t)), n
            }
    
            function er(t, n, r, e) {
                var u = -1,
                    o = t.length,
                    i = r.length,
                    f = -1,
                    c = n.length,
                    a = Tu(o - i, 0),
                    l = Array(c + a);
                for (e = !e; ++f < c;) l[f] = n[f];
                for (; ++u < i;)(e || o > u) && (l[r[u]] = t[u]);
                for (; a--;) l[f++] = t[u++];
                return l
            }
    
            function ur(t, n, r, e) {
                var u = -1,
                    o = t.length,
                    i = -1,
                    f = r.length,
                    c = -1,
                    a = n.length,
                    l = Tu(o - f, 0),
                    s = Array(l + a);
                for (e = !e; ++u < l;) s[u] = t[u];
                for (l = u; ++c < a;) s[l + c] = n[c];
                for (; ++i < f;)(e || o > u) && (s[l + r[i]] = t[u++]);
                return s
            }
    
            function or(t, n) {
                var r = -1,
                    e = t.length;
                for (n || (n = Array(e)); ++r < e;) n[r] = t[r];
                return n;
            }
    
            function ir(t, n, r, e) {
                r || (r = {});
                for (var u = -1, o = n.length; ++u < o;) {
                    var i = n[u],
                        f = e ? e(r[i], t[i], i, r, t) : t[i];
                    Xt(r, i, f)
                }
                return r
            }
    
            function fr(t, n) {
                return ir(t, Cr(t), n)
            }
    
            function cr(t, n) {
                return function(r, u) {
                    var o = oi(r) ? e : tn,
                        i = n ? n() : {};
                    return o(r, t, Rr(u), i)
                }
            }
    
            function ar(t) {
                return je(function(n, r) {
                    var e = -1,
                        u = r.length,
                        o = u > 1 ? r[u - 1] : q,
                        i = u > 2 ? r[2] : q,
                        o = typeof o == "function" ? (u--, o) : q;
                    for (i && Zr(r[0], r[1], i) && (o = 3 > u ? q : o, u = 1), n = Object(n); ++e < u;)(i = r[e]) && t(n, i, e, o);
                    return n
                })
            }
    
            function lr(t, n) {
                return function(r, e) {
                    if (null == r) return r;
                    if (!ke(r)) return t(r, e);
                    for (var u = r.length, o = n ? u : -1, i = Object(r);
                        (n ? o-- : ++o < u) && false !== e(i[o], o, i););
                    return r
                }
            }
    
            function sr(t) {
                return function(n, r, e) {
                    var u = -1,
                        o = Object(n);
                    e = e(n);
                    for (var i = e.length; i--;) {
                        var f = e[t ? i : ++u];
                        if (false === r(o[f], f, o)) break
                    }
                    return n
                }
            }
    
            function hr(t, n, r) {
                function e() {
                    return (this && this !== Yt && this instanceof e ? o : t).apply(u ? r : this, arguments)
                }
                var u = 1 & n,
                    o = vr(t);
                return e
            }
    
            function pr(t) {
                return function(n) {
                    n = Ke(n);
                    var r = Bt.test(n) ? n.match(Rt) : q,
                        e = r ? r[0] : n.charAt(0);
                    return n = r ? tr(r, 1).join("") : n.slice(1),
                        e[t]() + n
                }
            }
    
            function _r(t) {
                return function(n) {
                    return s(uu(eu(n).replace(It, "")), t, "")
                }
            }
    
            function vr(t) {
                return function() {
                    var n = arguments;
                    switch (n.length) {
                        case 0:
                            return new t;
                        case 1:
                            return new t(n[0]);
                        case 2:
                            return new t(n[0], n[1]);
                        case 3:
                            return new t(n[0], n[1], n[2]);
                        case 4:
                            return new t(n[0], n[1], n[2], n[3]);
                        case 5:
                            return new t(n[0], n[1], n[2], n[3], n[4]);
                        case 6:
                            return new t(n[0], n[1], n[2], n[3], n[4], n[5]);
                        case 7:
                            return new t(n[0], n[1], n[2], n[3], n[4], n[5], n[6])
                    }
                    var r = fn(t.prototype),
                        n = t.apply(r, n);
                    return Be(n) ? n : r;
                }
            }
    
            function gr(t, n, e) {
                function u() {
                    for (var i = arguments.length, f = Array(i), c = i, a = Lr(u); c--;) f[c] = arguments[c];
                    return c = 3 > i && f[0] !== a && f[i - 1] !== a ? [] : F(f, a), i -= c.length, e > i ? Ar(t, n, yr, u.placeholder, q, f, c, q, q, e - i) : r(this && this !== Yt && this instanceof u ? o : t, this, f)
                }
                var o = vr(t);
                return u
            }
    
            function dr(t) {
                return je(function(n) {
                    n = hn(n, 1);
                    var r = n.length,
                        e = r,
                        u = kt.prototype.thru;
                    for (t && n.reverse(); e--;) {
                        var o = n[e];
                        if (typeof o != "function") throw new vu("Expected a function");
                        if (u && !i && "wrapper" == Sr(o)) var i = new kt([], true);
                    }
                    for (e = i ? e : r; ++e < r;) var o = n[e],
                        u = Sr(o),
                        f = "wrapper" == u ? jo(o) : q,
                        i = f && Vr(f[0]) && 424 == f[1] && !f[4].length && 1 == f[9] ? i[Sr(f[0])].apply(i, f[3]) : 1 == o.length && Vr(o) ? i[u]() : i.thru(o);
                    return function() {
                        var t = arguments,
                            e = t[0];
                        if (i && 1 == t.length && oi(e) && e.length >= 200) return i.plant(e).value();
                        for (var u = 0, t = r ? n[u].apply(this, t) : e; ++u < r;) t = n[u].call(this, t);
                        return t
                    }
                })
            }
    
            function yr(t, n, r, e, u, o, i, f, c, a) {
                function l() {
                    for (var d = arguments.length, y = d, b = Array(d); y--;) b[y] = arguments[y];
                    if (_) {
                        var x, j = Lr(l),
                            y = b.length;
                        for (x = 0; y--;) b[y] === j && x++;
                    }
                    if (e && (b = er(b, e, u, _)), o && (b = ur(b, o, i, _)), d -= x, _ && a > d) return j = F(b, j), Ar(t, n, yr, l.placeholder, r, b, j, f, c, a - d);
                    if (j = h ? r : this, y = p ? j[t] : t, d = b.length, f) {
                        x = b.length;
                        for (var m = qu(f.length, x), w = or(b); m--;) {
                            var A = f[m];
                            b[m] = U(A, x) ? w[A] : q
                        }
                    } else v && d > 1 && b.reverse();
                    return s && d > c && (b.length = c), this && this !== Yt && this instanceof l && (y = g || vr(y)), y.apply(j, b)
                }
                var s = 128 & n,
                    h = 1 & n,
                    p = 2 & n,
                    _ = 24 & n,
                    v = 512 & n,
                    g = p ? q : vr(t);
                return l
            }
    
            function br(t, n) {
                return function(r, e) {
                    return jn(r, t, n(e))
                }
            }
    
            function xr(t) {
                return je(function(n) {
                    return n = 1 == n.length && oi(n[0]) ? a(n[0], O(Rr())) : a(hn(n, 1, Pr), O(Rr())),
                        je(function(e) {
                            var u = this;
                            return t(n, function(t) {
                                return r(t, u, e)
                            })
                        })
                })
            }
    
            function jr(t, n) {
                n = n === q ? " " : n + "";
                var r = n.length;
                return 2 > r ? r ? Fn(n, t) : n : (r = Fn(n, Du(t / P(n))), Bt.test(n) ? tr(r.match(Rt), 0, t).join("") : r.slice(0, t))
            }
    
            function mr(t, n, e, u) {
                function o() {
                    for (var n = -1, c = arguments.length, a = -1, l = u.length, s = Array(l + c), h = this && this !== Yt && this instanceof o ? f : t; ++a < l;) s[a] = u[a];
                    for (; c--;) s[a++] = arguments[++n];
                    return r(h, i ? e : this, s)
                }
                var i = 1 & n,
                    f = vr(t);
                return o
            }
    
            function wr(t) {
                return function(n, r, e) {
                    e && typeof e != "number" && Zr(n, r, e) && (r = e = q),
                        n = qe(n), n = n === n ? n : 0, r === q ? (r = n, n = 0) : r = qe(r) || 0, e = e === q ? r > n ? 1 : -1 : qe(e) || 0;
                    var u = -1;
                    r = Tu(Du((r - n) / (e || 1)), 0);
                    for (var o = Array(r); r--;) o[t ? r : ++u] = n, n += e;
                    return o
                }
            }
    
            function Ar(t, n, r, e, u, o, i, f, c, a) {
                var l = 8 & n,
                    s = l ? i : q;
                i = l ? q : i;
                var h = l ? o : q;
                return o = l ? q : o, n = (n | (l ? 32 : 64)) & ~(l ? 64 : 32), 4 & n || (n &= -4), n = [t, n, u, h, s, o, i, f, c, a], r = r.apply(q, n), Vr(t) && Ao(r, n), r.placeholder = e, r
            }
    
            function Or(t) {
                var n = pu[t];
                return function(t, r) {
                    if (t = qe(t), r = Ze(r)) {
                        var e = (Ke(t) + "e").split("e"),
                            e = n(e[0] + "e" + (+e[1] + r)),
                            e = (Ke(e) + "e").split("e");
                        return +(e[0] + "e" + (+e[1] - r))
                    }
                    return n(t)
                }
            }
    
            function kr(t, n, r, e, u, o, i, f) {
                var c = 2 & n;
                if (!c && typeof t != "function") throw new vu("Expected a function");
                var a = e ? e.length : 0;
                if (a || (n &= -97, e = u = q), i = i === q ? i : Tu(Ze(i), 0), f = f === q ? f : Ze(f), a -= u ? u.length : 0, 64 & n) {
                    var l = e,
                        s = u;
                    e = u = q
                }
                var h = c ? q : jo(t);
                return o = [t, n, r, e, u, l, s, o, i, f], h && (r = o[1], t = h[1], n = r | t, e = 128 == t && 8 == r || 128 == t && 256 == r && h[8] >= o[7].length || 384 == t && h[8] >= h[7].length && 8 == r, 131 > n || e) && (1 & t && (o[2] = h[2], n |= 1 & r ? 0 : 4), (r = h[3]) && (e = o[3], o[3] = e ? er(e, r, h[4]) : r, o[4] = e ? F(o[3], "__lodash_placeholder__") : h[4]),
                    (r = h[5]) && (e = o[5], o[5] = e ? ur(e, r, h[6]) : r, o[6] = e ? F(o[5], "__lodash_placeholder__") : h[6]), (r = h[7]) && (o[7] = r), 128 & t && (o[8] = null == o[8] ? h[8] : qu(o[8], h[8])), null == o[9] && (o[9] = h[9]), o[0] = h[0], o[1] = n), t = o[0], n = o[1], r = o[2], e = o[3], u = o[4], f = o[9] = null == o[9] ? c ? 0 : t.length : Tu(o[9] - a, 0), !f && 24 & n && (n &= -25), (h ? bo : Ao)(n && 1 != n ? 8 == n || 16 == n ? gr(t, n, f) : 32 != n && 33 != n || u.length ? yr.apply(q, o) : mr(t, n, r, e) : hr(t, n, r), o)
            }
    
            function Er(t, n, r, e, u, o) {
                var i = -1,
                    f = 2 & u,
                    c = 1 & u,
                    a = t.length,
                    l = n.length;
                if (!(a == l || f && l > a)) return false;
                if (l = o.get(t)) return l == n;
                for (l = true, o.set(t, n); ++i < a;) {
                    var s = t[i],
                        h = n[i];
                    if (e) var _ = f ? e(h, s, i, n, t, o) : e(s, h, i, t, n, o);
                    if (_ !== q) {
                        if (_) continue;
                        l = false;
                        break
                    }
                    if (c) {
                        if (!p(n, function(t) {
                                return s === t || r(s, t, e, u, o)
                            })) {
                            l = false;
                            break
                        }
                    } else if (s !== h && !r(s, h, e, u, o)) {
                        l = false;
                        break
                    }
                }
                return o["delete"](t), l
            }
    
            function Ir(t, n, r, e, u, o, i) {
                switch (r) {
                    case "[object DataView]":
                        if (t.byteLength != n.byteLength || t.byteOffset != n.byteOffset) break;
                        t = t.buffer, n = n.buffer;
                    case "[object ArrayBuffer]":
                        if (t.byteLength != n.byteLength || !e(new Su(t), new Su(n))) break;
                        return true;
                    case "[object Boolean]":
                    case "[object Date]":
                        return +t == +n;
                    case "[object Error]":
                        return t.name == n.name && t.message == n.message;
                    case "[object Number]":
                        return t != +t ? n != +n : t == +n;
                    case "[object RegExp]":
                    case "[object String]":
                        return t == n + "";
                    case "[object Map]":
                        var f = $;
                    case "[object Set]":
                        if (f || (f = N), t.size != n.size && !(2 & o)) break;
                        return (r = i.get(t)) ? r == n : (o |= 1, i.set(t, n), Er(f(t), f(n), e, u, o, i));
                    case "[object Symbol]":
                        if (ho) return ho.call(t) == ho.call(n)
                }
                return false
            }
    
            function Sr(t) {
                for (var n = t.name + "", r = oo[n], e = xu.call(oo, n) ? r.length : 0; e--;) {
                    var u = r[e],
                        o = u.func;
                    if (null == o || o == t) return u.name
                }
                return n
            }
    
            function Rr() {
                var t = jt.iteratee || fu,
                    t = t === fu ? On : t;
                return arguments.length ? t(arguments[0], arguments[1]) : t
            }
    
            function Wr(t) {
                t = Xe(t);
                for (var n = t.length; n--;) {
                    var r = t[n][1];
                    t[n][2] = r === r && !Be(r)
                }
                return t
            }
    
            function Br(t, n) {
                var r = t[n];
                return Ce(r) ? r : q
            }
    
            function Lr(t) {
                return (xu.call(jt, "placeholder") ? jt : t).placeholder
            }
    
            function Cr(t) {
                return Bu(Object(t))
            }
    
            function Mr(t) {
                return wu.call(t)
            }
    
            function zr(t, n, r) {
                n = Tr(n, t) ? [n] : Xn(n);
                for (var e, u = -1, o = n.length; ++u < o;) {
                    var i = n[u];
                    if (!(e = null != t && r(t, i))) break;
                    t = t[i]
                }
                return e ? e : (o = t ? t.length : 0, !!o && We(o) && U(i, o) && (oi(t) || De(t) || Oe(t)))
            }
    
            function Ur(t) {
                var n = t.length,
                    r = t.constructor(n);
                return n && "string" == typeof t[0] && xu.call(t, "index") && (r.index = t.index, r.input = t.input), r
            }
    
            function Dr(t) {
                return typeof t.constructor != "function" || Kr(t) ? {} : fn(Fu(Object(t)))
            }
    
            function $r(r, e, u, o) {
                var i = r.constructor;
                switch (e) {
                    case "[object ArrayBuffer]":
                        return rr(r);
                    case "[object Boolean]":
                    case "[object Date]":
                        return new i(+r);
                    case "[object DataView]":
                        return e = o ? rr(r.buffer) : r.buffer, new r.constructor(e, r.byteOffset, r.byteLength);
                    case "[object Float32Array]":
                    case "[object Float64Array]":
                    case "[object Int8Array]":
                    case "[object Int16Array]":
                    case "[object Int32Array]":
                    case "[object Uint8Array]":
                    case "[object Uint8ClampedArray]":
                    case "[object Uint16Array]":
                    case "[object Uint32Array]":
                        return e = o ? rr(r.buffer) : r.buffer, new r.constructor(e, r.byteOffset, r.length);
                    case "[object Map]":
                        return e = o ? u($(r), true) : $(r), s(e, t, new r.constructor);
                    case "[object Number]":
                    case "[object String]":
                        return new i(r);
                    case "[object RegExp]":
                        return e = new r.constructor(r.source, vt.exec(r)), e.lastIndex = r.lastIndex, e;
                    case "[object Set]":
                        return e = o ? u(N(r), true) : N(r), s(e, n, new r.constructor);
                    case "[object Symbol]":
                        return ho ? Object(ho.call(r)) : {}
                }
            }
    
            function Fr(t) {
                var n = t ? t.length : q;
                return We(n) && (oi(t) || De(t) || Oe(t)) ? w(n, String) : null
            }
    
            function Nr(t) {
                return Ee(t) && (oi(t) || Oe(t))
            }
    
            function Pr(t) {
                return oi(t) && !(2 == t.length && !Se(t[0]))
            }
    
            function Zr(t, n, r) {
                if (!Be(r)) return false;
                var e = typeof n;
                return ("number" == e ? ke(r) && U(n, r.length) : "string" == e && n in r) ? we(r[n], t) : false;
            }
    
            function Tr(t, n) {
                var r = typeof t;
                return "number" == r || "symbol" == r ? true : !oi(t) && ($e(t) || ot.test(t) || !ut.test(t) || null != n && t in Object(n))
            }
    
            function qr(t) {
                var n = typeof t;
                return "number" == n || "boolean" == n || "string" == n && "__proto__" != t || null == t
            }
    
            function Vr(t) {
                var n = Sr(t),
                    r = jt[n];
                return typeof r == "function" && n in Et.prototype ? t === r ? true : (n = jo(r), !!n && t === n[0]) : false
            }
    
            function Kr(t) {
                var n = t && t.constructor;
                return t === (typeof n == "function" && n.prototype || du)
            }
    
            function Gr(t, n) {
                return function(r) {
                    return null == r ? false : r[t] === n && (n !== q || t in Object(r));
                }
            }
    
            function Jr(t, n, r, e, u, o) {
                return Be(t) && Be(n) && Rn(t, n, q, Jr, o.set(n, t)), t
            }
    
            function Yr(t, n) {
                return 1 == n.length ? t : gn(t, Pn(n, 0, -1))
            }
    
            function Hr(t) {
                return typeof t == "string" || $e(t) ? t : t + ""
            }
    
            function Qr(t) {
                if (null != t) {
                    try {
                        return bu.call(t)
                    } catch (n) {}
                    return t + ""
                }
                return ""
            }
    
            function Xr(t) {
                if (t instanceof Et) return t.clone();
                var n = new kt(t.__wrapped__, t.__chain__);
                return n.__actions__ = or(t.__actions__), n.__index__ = t.__index__, n.__values__ = t.__values__, n
            }
    
            function te(t, n, r) {
                var e = t ? t.length : 0;
                return e ? (n = r || n === q ? 1 : Ze(n),
                    Pn(t, 0 > n ? 0 : n, e)) : []
            }
    
            function ne(t, n, r) {
                var e = t ? t.length : 0;
                return e ? (n = r || n === q ? 1 : Ze(n), n = e - n, Pn(t, 0, 0 > n ? 0 : n)) : []
            }
    
            function re(t) {
                return t && t.length ? t[0] : q
            }
    
            function ee(t) {
                var n = t ? t.length : 0;
                return n ? t[n - 1] : q
            }
    
            function ue(t, n) {
                return t && t.length && n && n.length ? Un(t, n) : t
            }
    
            function oe(t) {
                return t ? Ju.call(t) : t
            }
    
            function ie(t) {
                if (!t || !t.length) return [];
                var n = 0;
                return t = i(t, function(t) {
                    return Ee(t) ? (n = Tu(t.length, n), true) : void 0
                }), w(n, function(n) {
                    return a(t, Mn(n))
                })
            }
    
            function fe(t, n) {
                if (!t || !t.length) return [];
                var e = ie(t);
                return null == n ? e : a(e, function(t) {
                    return r(n, q, t)
                })
            }
    
            function ce(t) {
                return t = jt(t), t.__chain__ = true, t
            }
    
            function ae(t, n) {
                return n(t)
            }
    
            function le() {
                return this
            }
    
            function se(t, n) {
                return typeof n == "function" && oi(t) ? u(t, n) : _o(t, Rr(n))
            }
    
            function he(t, n) {
                var r;
                if (typeof n == "function" && oi(t)) {
                    for (r = t.length; r-- && false !== n(t[r], r, t););
                    r = t
                } else r = vo(t, Rr(n));
                return r
            }
    
            function pe(t, n) {
                return (oi(t) ? a : En)(t, Rr(n, 3))
            }
    
            function _e(t, n, r) {
                var e = -1,
                    u = Pe(t),
                    o = u.length,
                    i = o - 1;
                for (n = (r ? Zr(t, n, r) : n === q) ? 1 : en(Ze(n), 0, o); ++e < n;) t = $n(e, i),
                    r = u[t], u[t] = u[e], u[e] = r;
                return u.length = n, u
            }
    
            function ve(t, n, r) {
                return n = r ? q : n, n = t && null == n ? t.length : n, kr(t, 128, q, q, q, q, n)
            }
    
            function ge(t, n) {
                var r;
                if (typeof n != "function") throw new vu("Expected a function");
                return t = Ze(t),
                    function() {
                        return 0 < --t && (r = n.apply(this, arguments)), 1 >= t && (n = q), r
                    }
            }
    
            function de(t, n, r) {
                return n = r ? q : n, t = kr(t, 8, q, q, q, q, q, n), t.placeholder = de.placeholder, t
            }
    
            function ye(t, n, r) {
                return n = r ? q : n, t = kr(t, 16, q, q, q, q, q, n), t.placeholder = ye.placeholder, t
            }
    
            function be(t, n, r) {
                function e(n) {
                    var r = c,
                        e = a;
                    return c = a = q, p = n, l = t.apply(e, r)
                }
    
                function u(t) {
                    var r = t - h;
                    return t -= p, !h || r >= n || 0 > r || false !== v && t >= v
                }
    
                function o() {
                    var t = Yo();
                    if (u(t)) return i(t);
                    var r;
                    r = t - p, t = n - (t - h), r = false === v ? t : qu(t, v - r), s = zu(o, r)
                }
    
                function i(t) {
                    return Ru(s), s = q, g && c ? e(t) : (c = a = q, l)
                }
    
                function f() {
                    var t = Yo(),
                        r = u(t);
                    return c = arguments, a = this, h = t, r ? s === q ? (p = t = h, s = zu(o, n), _ ? e(t) : l) : (Ru(s), s = zu(o, n), e(h)) : (s === q && (s = zu(o, n)), l)
                }
                var c, a, l, s, h = 0,
                    p = 0,
                    _ = false,
                    v = false,
                    g = true;
                if (typeof t != "function") throw new vu("Expected a function");
                return n = qe(n) || 0, Be(r) && (_ = !!r.leading,
                    v = "maxWait" in r && Tu(qe(r.maxWait) || 0, n), g = "trailing" in r ? !!r.trailing : g), f.cancel = function() {
                    s !== q && Ru(s), h = p = 0, c = a = s = q
                }, f.flush = function() {
                    return s === q ? l : i(Yo())
                }, f
            }
    
            function xe(t, n) {
                function r() {
                    var e = arguments,
                        u = n ? n.apply(this, e) : e[0],
                        o = r.cache;
                    return o.has(u) ? o.get(u) : (e = t.apply(this, e), r.cache = o.set(u, e), e)
                }
                if (typeof t != "function" || n && typeof n != "function") throw new vu("Expected a function");
                return r.cache = new(xe.Cache || Dt), r
            }
    
            function je(t, n) {
                if (typeof t != "function") throw new vu("Expected a function");
                return n = Tu(n === q ? t.length - 1 : Ze(n), 0),
                    function() {
                        for (var e = arguments, u = -1, o = Tu(e.length - n, 0), i = Array(o); ++u < o;) i[u] = e[n + u];
                        switch (n) {
                            case 0:
                                return t.call(this, i);
                            case 1:
                                return t.call(this, e[0], i);
                            case 2:
                                return t.call(this, e[0], e[1], i)
                        }
                        for (o = Array(n + 1), u = -1; ++u < n;) o[u] = e[u];
                        return o[n] = i, r(t, this, o)
                    }
            }
    
            function me() {
                if (!arguments.length) return [];
                var t = arguments[0];
                return oi(t) ? t : [t]
            }
    
            function we(t, n) {
                return t === n || t !== t && n !== n
            }
    
            function Ae(t, n) {
                return t > n
            }
    
            function Oe(t) {
                return Ee(t) && xu.call(t, "callee") && (!Mu.call(t, "callee") || "[object Arguments]" == wu.call(t));
            }
    
            function ke(t) {
                return null != t && We(mo(t)) && !Se(t)
            }
    
            function Ee(t) {
                return Le(t) && ke(t)
            }
    
            function Ie(t) {
                return Le(t) ? "[object Error]" == wu.call(t) || typeof t.message == "string" && typeof t.name == "string" : false
            }
    
            function Se(t) {
                return t = Be(t) ? wu.call(t) : "", "[object Function]" == t || "[object GeneratorFunction]" == t
            }
    
            function Re(t) {
                return typeof t == "number" && t == Ze(t)
            }
    
            function We(t) {
                return typeof t == "number" && t > -1 && 0 == t % 1 && 9007199254740991 >= t
            }
    
            function Be(t) {
                var n = typeof t;
                return !!t && ("object" == n || "function" == n)
            }
    
            function Le(t) {
                return !!t && typeof t == "object"
            }
    
            function Ce(t) {
                return Be(t) ? (Se(t) || z(t) ? Ou : bt).test(Qr(t)) : false
            }
    
            function Me(t) {
                return typeof t == "number" || Le(t) && "[object Number]" == wu.call(t)
            }
    
            function ze(t) {
                return !Le(t) || "[object Object]" != wu.call(t) || z(t) ? false : (t = Fu(Object(t)), null === t ? true : (t = xu.call(t, "constructor") && t.constructor, typeof t == "function" && t instanceof t && bu.call(t) == mu))
            }
    
            function Ue(t) {
                return Be(t) && "[object RegExp]" == wu.call(t)
            }
    
            function De(t) {
                return typeof t == "string" || !oi(t) && Le(t) && "[object String]" == wu.call(t);
            }
    
            function $e(t) {
                return typeof t == "symbol" || Le(t) && "[object Symbol]" == wu.call(t)
            }
    
            function Fe(t) {
                return Le(t) && We(t.length) && !!Mt[wu.call(t)]
            }
    
            function Ne(t, n) {
                return n > t
            }
    
            function Pe(t) {
                if (!t) return [];
                if (ke(t)) return De(t) ? t.match(Rt) : or(t);
                if (Lu && t[Lu]) return D(t[Lu]());
                var n = Mr(t);
                return ("[object Map]" == n ? $ : "[object Set]" == n ? N : nu)(t)
            }
    
            function Ze(t) {
                if (!t) return 0 === t ? t : 0;
                if (t = qe(t), t === V || t === -V) return 1.7976931348623157e308 * (0 > t ? -1 : 1);
                var n = t % 1;
                return t === t ? n ? t - n : t : 0
            }
    
            function Te(t) {
                return t ? en(Ze(t), 0, 4294967295) : 0;
            }
    
            function qe(t) {
                if (typeof t == "number") return t;
                if ($e(t)) return K;
                if (Be(t) && (t = Se(t.valueOf) ? t.valueOf() : t, t = Be(t) ? t + "" : t), typeof t != "string") return 0 === t ? t : +t;
                t = t.replace(at, "");
                var n = yt.test(t);
                return n || xt.test(t) ? Zt(t.slice(2), n ? 2 : 8) : dt.test(t) ? K : +t
            }
    
            function Ve(t) {
                return ir(t, Qe(t))
            }
    
            function Ke(t) {
                if (typeof t == "string") return t;
                if (null == t) return "";
                if ($e(t)) return po ? po.call(t) : "";
                var n = t + "";
                return "0" == n && 1 / t == -V ? "-0" : n
            }
    
            function Ge(t, n, r) {
                return t = null == t ? q : gn(t, n), t === q ? r : t
            }
    
            function Je(t, n) {
                return null != t && zr(t, n, yn);
            }
    
            function Ye(t, n) {
                return null != t && zr(t, n, bn)
            }
    
            function He(t) {
                var n = Kr(t);
                if (!n && !ke(t)) return Zu(Object(t));
                var r, e = Fr(t),
                    u = !!e,
                    e = e || [],
                    o = e.length;
                for (r in t) !yn(t, r) || u && ("length" == r || U(r, o)) || n && "constructor" == r || e.push(r);
                return e
            }
    
            function Qe(t) {
                for (var n = -1, r = Kr(t), e = kn(t), u = e.length, o = Fr(t), i = !!o, o = o || [], f = o.length; ++n < u;) {
                    var c = e[n];
                    i && ("length" == c || U(c, f)) || "constructor" == c && (r || !xu.call(t, c)) || o.push(c)
                }
                return o
            }
    
            function Xe(t) {
                return A(t, He(t))
            }
    
            function tu(t) {
                return A(t, Qe(t))
            }
    
            function nu(t) {
                return t ? k(t, He(t)) : []
            }
    
            function ru(t) {
                return Ii(Ke(t).toLowerCase())
            }
    
            function eu(t) {
                return (t = Ke(t)) && t.replace(mt, B).replace(St, "")
            }
    
            function uu(t, n, r) {
                return t = Ke(t), n = r ? q : n, n === q && (n = Lt.test(t) ? Wt : ht), t.match(n) || []
            }
    
            function ou(t) {
                return function() {
                    return t
                }
            }
    
            function iu(t) {
                return t
            }
    
            function fu(t) {
                return On(typeof t == "function" ? t : un(t, true))
            }
    
            function cu(t, n, r) {
                var e = He(n),
                    o = vn(n, e);
                null != r || Be(n) && (o.length || !e.length) || (r = n, n = t, t = this, o = vn(n, He(n)));
                var i = Be(r) && "chain" in r ? r.chain : true,
                    f = Se(t);
                return u(o, function(r) {
                    var e = n[r];
                    t[r] = e, f && (t.prototype[r] = function() {
                        var n = this.__chain__;
                        if (i || n) {
                            var r = t(this.__wrapped__);
                            return (r.__actions__ = or(this.__actions__)).push({
                                func: e,
                                args: arguments,
                                thisArg: t
                            }), r.__chain__ = n, r
                        }
                        return e.apply(t, l([this.value()], arguments))
                    })
                }), t
            }
    
            function au() {}
    
            function lu(t) {
                return Tr(t) ? Mn(t) : zn(t)
            }
            S = S ? Ht.defaults({}, S, Ht.pick(Yt, Ct)) : Yt;
            var su = S.Date,
                hu = S.Error,
                pu = S.Math,
                _u = S.RegExp,
                vu = S.TypeError,
                gu = S.Array.prototype,
                du = S.Object.prototype,
                yu = S.String.prototype,
                bu = S.Function.prototype.toString,
                xu = du.hasOwnProperty,
                ju = 0,
                mu = bu.call(Object),
                wu = du.toString,
                Au = Yt._,
                Ou = _u("^" + bu.call(xu).replace(ft, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$"),
                ku = Vt ? S.Buffer : q,
                Eu = S.Reflect,
                Iu = S.Symbol,
                Su = S.Uint8Array,
                Ru = S.clearTimeout,
                Wu = Eu ? Eu.f : q,
                Bu = Object.getOwnPropertySymbols,
                Lu = typeof(Lu = Iu && Iu.iterator) == "symbol" ? Lu : q,
                Cu = Object.create,
                Mu = du.propertyIsEnumerable,
                zu = S.setTimeout,
                Uu = gu.splice,
                Du = pu.ceil,
                $u = pu.floor,
                Fu = Object.getPrototypeOf,
                Nu = S.isFinite,
                Pu = gu.join,
                Zu = Object.keys,
                Tu = pu.max,
                qu = pu.min,
                Vu = S.parseInt,
                Ku = pu.random,
                Gu = yu.replace,
                Ju = gu.reverse,
                Yu = yu.split,
                Hu = Br(S, "DataView"),
                Qu = Br(S, "Map"),
                Xu = Br(S, "Promise"),
                to = Br(S, "Set"),
                no = Br(S, "WeakMap"),
                ro = Br(Object, "create"),
                eo = no && new no,
                uo = !Mu.call({
                    valueOf: 1
                }, "valueOf"),
                oo = {},
                io = Qr(Hu),
                fo = Qr(Qu),
                co = Qr(Xu),
                ao = Qr(to),
                lo = Qr(no),
                so = Iu ? Iu.prototype : q,
                ho = so ? so.valueOf : q,
                po = so ? so.toString : q;
            jt.templateSettings = {
                escape: nt,
                evaluate: rt,
                interpolate: et,
                variable: "",
                imports: {
                    _: jt
                }
            }, jt.prototype = Ot.prototype, jt.prototype.constructor = jt, kt.prototype = fn(Ot.prototype), kt.prototype.constructor = kt, Et.prototype = fn(Ot.prototype), Et.prototype.constructor = Et, Ut.prototype = ro ? ro(null) : du, Dt.prototype.clear = function() {
                this.__data__ = {
                    hash: new Ut,
                    map: Qu ? new Qu : [],
                    string: new Ut
                }
            }, Dt.prototype["delete"] = function(t) {
                var n = this.__data__;
                return qr(t) ? (n = typeof t == "string" ? n.string : n.hash, t = (ro ? n[t] !== q : xu.call(n, t)) && delete n[t]) : t = Qu ? n.map["delete"](t) : Tt(n.map, t), t
            }, Dt.prototype.get = function(t) {
                var n = this.__data__;
                return qr(t) ? (n = typeof t == "string" ? n.string : n.hash, ro ? (t = n[t], t = "__lodash_hash_undefined__" === t ? q : t) : t = xu.call(n, t) ? n[t] : q) : t = Qu ? n.map.get(t) : qt(n.map, t), t
            }, Dt.prototype.has = function(t) {
                var n = this.__data__;
                return qr(t) ? (n = typeof t == "string" ? n.string : n.hash, t = ro ? n[t] !== q : xu.call(n, t)) : t = Qu ? n.map.has(t) : -1 < Kt(n.map, t),
                    t
            }, Dt.prototype.set = function(t, n) {
                var r = this.__data__;
                return qr(t) ? (typeof t == "string" ? r.string : r.hash)[t] = ro && n === q ? "__lodash_hash_undefined__" : n : Qu ? r.map.set(t, n) : Gt(r.map, t, n), this
            }, $t.prototype.push = function(t) {
                var n = this.__data__;
                qr(t) ? (n = n.__data__, (typeof t == "string" ? n.string : n.hash)[t] = "__lodash_hash_undefined__") : n.set(t, "__lodash_hash_undefined__")
            }, Nt.prototype.clear = function() {
                this.__data__ = {
                    array: [],
                    map: null
                }
            }, Nt.prototype["delete"] = function(t) {
                var n = this.__data__,
                    r = n.array;
                return r ? Tt(r, t) : n.map["delete"](t);
            }, Nt.prototype.get = function(t) {
                var n = this.__data__,
                    r = n.array;
                return r ? qt(r, t) : n.map.get(t)
            }, Nt.prototype.has = function(t) {
                var n = this.__data__,
                    r = n.array;
                return r ? -1 < Kt(r, t) : n.map.has(t)
            }, Nt.prototype.set = function(t, n) {
                var r = this.__data__,
                    e = r.array;
                return e && (199 > e.length ? Gt(e, t, n) : (r.array = null, r.map = new Dt(e))), (r = r.map) && r.set(t, n), this
            };
            var _o = lr(pn),
                vo = lr(_n, true),
                go = sr(),
                yo = sr(true);
            Wu && !Mu.call({
                valueOf: 1
            }, "valueOf") && (kn = function(t) {
                return D(Wu(t))
            });
            var bo = eo ? function(t, n) {
                    return eo.set(t, n), t
                } : iu,
                xo = to && 2 === new to([1, 2]).size ? function(t) {
                    return new to(t)
                } : au,
                jo = eo ? function(t) {
                    return eo.get(t)
                } : au,
                mo = Mn("length");
            Bu || (Cr = function() {
                return []
            });
            var wo = Bu ? function(t) {
                for (var n = []; t;) l(n, Cr(t)), t = Fu(Object(t));
                return n
            } : Cr;
            (Hu && "[object DataView]" != Mr(new Hu(new ArrayBuffer(1))) || Qu && "[object Map]" != Mr(new Qu) || Xu && "[object Promise]" != Mr(Xu.resolve()) || to && "[object Set]" != Mr(new to) || no && "[object WeakMap]" != Mr(new no)) && (Mr = function(t) {
                var n = wu.call(t);
                if (t = (t = "[object Object]" == n ? t.constructor : q) ? Qr(t) : q) switch (t) {
                    case io:
                        return "[object DataView]";
                    case fo:
                        return "[object Map]";
                    case co:
                        return "[object Promise]";
                    case ao:
                        return "[object Set]";
                    case lo:
                        return "[object WeakMap]"
                }
                return n
            });
            var Ao = function() {
                    var t = 0,
                        n = 0;
                    return function(r, e) {
                        var u = Yo(),
                            o = 16 - (u - n);
                        if (n = u, o > 0) {
                            if (150 <= ++t) return r
                        } else t = 0;
                        return bo(r, e)
                    }
                }(),
                Oo = xe(function(t) {
                    var n = [];
                    return Ke(t).replace(it, function(t, r, e, u) {
                        n.push(e ? u.replace(pt, "$1") : r || t)
                    }), n
                }),
                ko = je(function(t, n) {
                    return Ee(t) ? an(t, hn(n, 1, Ee, true)) : []
                }),
                Eo = je(function(t, n) {
                    var r = ee(n);
                    return Ee(r) && (r = q), Ee(t) ? an(t, hn(n, 1, Ee, true), Rr(r)) : [];
                }),
                Io = je(function(t, n) {
                    var r = ee(n);
                    return Ee(r) && (r = q), Ee(t) ? an(t, hn(n, 1, Ee, true), q, r) : []
                }),
                So = je(function(t) {
                    var n = a(t, Qn);
                    return n.length && n[0] === t[0] ? xn(n) : []
                }),
                Ro = je(function(t) {
                    var n = ee(t),
                        r = a(t, Qn);
                    return n === ee(r) ? n = q : r.pop(), r.length && r[0] === t[0] ? xn(r, Rr(n)) : []
                }),
                Wo = je(function(t) {
                    var n = ee(t),
                        r = a(t, Qn);
                    return n === ee(r) ? n = q : r.pop(), r.length && r[0] === t[0] ? xn(r, q, n) : []
                }),
                Bo = je(ue),
                Lo = je(function(t, n) {
                    n = a(hn(n, 1), String);
                    var r = rn(t, n);
                    return Dn(t, n.sort(R)), r
                }),
                Co = je(function(t) {
                    return Kn(hn(t, 1, Ee, true));
                }),
                Mo = je(function(t) {
                    var n = ee(t);
                    return Ee(n) && (n = q), Kn(hn(t, 1, Ee, true), Rr(n))
                }),
                zo = je(function(t) {
                    var n = ee(t);
                    return Ee(n) && (n = q), Kn(hn(t, 1, Ee, true), q, n)
                }),
                Uo = je(function(t, n) {
                    return Ee(t) ? an(t, n) : []
                }),
                Do = je(function(t) {
                    return Yn(i(t, Ee))
                }),
                $o = je(function(t) {
                    var n = ee(t);
                    return Ee(n) && (n = q), Yn(i(t, Ee), Rr(n))
                }),
                Fo = je(function(t) {
                    var n = ee(t);
                    return Ee(n) && (n = q), Yn(i(t, Ee), q, n)
                }),
                No = je(ie),
                Po = je(function(t) {
                    var n = t.length,
                        n = n > 1 ? t[n - 1] : q,
                        n = typeof n == "function" ? (t.pop(), n) : q;
                    return fe(t, n)
                }),
                Zo = je(function(t) {
                    function n(n) {
                        return rn(n, t)
                    }
                    t = hn(t, 1);
                    var r = t.length,
                        e = r ? t[0] : 0,
                        u = this.__wrapped__;
                    return 1 >= r && !this.__actions__.length && u instanceof Et && U(e) ? (u = u.slice(e, +e + (r ? 1 : 0)), u.__actions__.push({
                        func: ae,
                        args: [n],
                        thisArg: q
                    }), new kt(u, this.__chain__).thru(function(t) {
                        return r && !t.length && t.push(q), t
                    })) : this.thru(n)
                }),
                To = cr(function(t, n, r) {
                    xu.call(t, r) ? ++t[r] : t[r] = 1
                }),
                qo = cr(function(t, n, r) {
                    xu.call(t, r) ? t[r].push(n) : t[r] = [n]
                }),
                Vo = je(function(t, n, e) {
                    var u = -1,
                        o = typeof n == "function",
                        i = Tr(n),
                        f = ke(t) ? Array(t.length) : [];
                    return _o(t, function(t) {
                        var c = o ? n : i && null != t ? t[n] : q;
                        f[++u] = c ? r(c, t, e) : mn(t, n, e)
                    }), f
                }),
                Ko = cr(function(t, n, r) {
                    t[r] = n
                }),
                Go = cr(function(t, n, r) {
                    t[r ? 0 : 1].push(n)
                }, function() {
                    return [
                        [],
                        []
                    ]
                }),
                Jo = je(function(t, n) {
                    if (null == t) return [];
                    var r = n.length;
                    return r > 1 && Zr(t, n[0], n[1]) ? n = [] : r > 2 && Zr(n[0], n[1], n[2]) && (n = [n[0]]), n = 1 == n.length && oi(n[0]) ? n[0] : hn(n, 1, Pr), Bn(t, n, [])
                }),
                Yo = su.now,
                Ho = je(function(t, n, r) {
                    var e = 1;
                    if (r.length) var u = F(r, Lr(Ho)),
                        e = 32 | e;
                    return kr(t, e, n, r, u)
                }),
                Qo = je(function(t, n, r) {
                    var e = 3;
                    if (r.length) var u = F(r, Lr(Qo)),
                        e = 32 | e;
                    return kr(n, e, t, r, u)
                }),
                Xo = je(function(t, n) {
                    return cn(t, 1, n)
                }),
                ti = je(function(t, n, r) {
                    return cn(t, qe(n) || 0, r)
                });
            xe.Cache = Dt;
            var ni = je(function(t, n) {
                    n = 1 == n.length && oi(n[0]) ? a(n[0], O(Rr())) : a(hn(n, 1, Pr), O(Rr()));
                    var e = n.length;
                    return je(function(u) {
                        for (var o = -1, i = qu(u.length, e); ++o < i;) u[o] = n[o].call(this, u[o]);
                        return r(t, this, u)
                    })
                }),
                ri = je(function(t, n) {
                    var r = F(n, Lr(ri));
                    return kr(t, 32, q, n, r)
                }),
                ei = je(function(t, n) {
                    var r = F(n, Lr(ei));
                    return kr(t, 64, q, n, r)
                }),
                ui = je(function(t, n) {
                    return kr(t, 256, q, q, q, hn(n, 1));
                }),
                oi = Array.isArray,
                ii = ku ? function(t) {
                    return t instanceof ku
                } : ou(false),
                fi = ar(function(t, n) {
                    if (uo || Kr(n) || ke(n)) ir(n, He(n), t);
                    else
                        for (var r in n) xu.call(n, r) && Xt(t, r, n[r])
                }),
                ci = ar(function(t, n) {
                    if (uo || Kr(n) || ke(n)) ir(n, Qe(n), t);
                    else
                        for (var r in n) Xt(t, r, n[r])
                }),
                ai = ar(function(t, n, r, e) {
                    ir(n, Qe(n), t, e)
                }),
                li = ar(function(t, n, r, e) {
                    ir(n, He(n), t, e)
                }),
                si = je(function(t, n) {
                    return rn(t, hn(n, 1))
                }),
                hi = je(function(t) {
                    return t.push(q, Jt), r(ai, q, t)
                }),
                pi = je(function(t) {
                    return t.push(q, Jr), r(yi, q, t)
                }),
                _i = br(function(t, n, r) {
                    t[n] = r
                }, ou(iu)),
                vi = br(function(t, n, r) {
                    xu.call(t, n) ? t[n].push(r) : t[n] = [r]
                }, Rr),
                gi = je(mn),
                di = ar(function(t, n, r) {
                    Rn(t, n, r)
                }),
                yi = ar(function(t, n, r, e) {
                    Rn(t, n, r, e)
                }),
                bi = je(function(t, n) {
                    return null == t ? {} : (n = a(hn(n, 1), Hr), Ln(t, an(dn(t, Qe, wo), n)))
                }),
                xi = je(function(t, n) {
                    return null == t ? {} : Ln(t, hn(n, 1))
                }),
                ji = _r(function(t, n, r) {
                    return n = n.toLowerCase(), t + (r ? ru(n) : n)
                }),
                mi = _r(function(t, n, r) {
                    return t + (r ? "-" : "") + n.toLowerCase()
                }),
                wi = _r(function(t, n, r) {
                    return t + (r ? " " : "") + n.toLowerCase()
                }),
                Ai = pr("toLowerCase"),
                Oi = _r(function(t, n, r) {
                    return t + (r ? "_" : "") + n.toLowerCase()
                }),
                ki = _r(function(t, n, r) {
                    return t + (r ? " " : "") + Ii(n)
                }),
                Ei = _r(function(t, n, r) {
                    return t + (r ? " " : "") + n.toUpperCase()
                }),
                Ii = pr("toUpperCase"),
                Si = je(function(t, n) {
                    try {
                        return r(t, q, n)
                    } catch (e) {
                        return Ie(e) ? e : new hu(e)
                    }
                }),
                Ri = je(function(t, n) {
                    return u(hn(n, 1), function(n) {
                        t[n] = Ho(t[n], t)
                    }), t
                }),
                Wi = dr(),
                Bi = dr(true),
                Li = je(function(t, n) {
                    return function(r) {
                        return mn(r, t, n)
                    }
                }),
                Ci = je(function(t, n) {
                    return function(r) {
                        return mn(t, r, n)
                    }
                }),
                Mi = xr(a),
                zi = xr(o),
                Ui = xr(p),
                Di = wr(),
                $i = wr(true),
                Fi = W(function(t, n) {
                    return t + n
                }),
                Ni = Or("ceil"),
                Pi = W(function(t, n) {
                    return t / n
                }),
                Zi = Or("floor"),
                Ti = W(function(t, n) {
                    return t * n
                }),
                qi = Or("round"),
                Vi = W(function(t, n) {
                    return t - n
                });
            return jt.after = function(t, n) {
                    if (typeof n != "function") throw new vu("Expected a function");
                    return t = Ze(t),
                        function() {
                            return 1 > --t ? n.apply(this, arguments) : void 0
                        }
                }, jt.ary = ve, jt.assign = fi, jt.assignIn = ci, jt.assignInWith = ai, jt.assignWith = li, jt.at = si, jt.before = ge, jt.bind = Ho, jt.bindAll = Ri, jt.bindKey = Qo, jt.castArray = me, jt.chain = ce, jt.chunk = function(t, n, r) {
                    if (n = (r ? Zr(t, n, r) : n === q) ? 1 : Tu(Ze(n), 0), r = t ? t.length : 0, !r || 1 > n) return [];
                    for (var e = 0, u = 0, o = Array(Du(r / n)); r > e;) o[u++] = Pn(t, e, e += n);
                    return o
                }, jt.compact = function(t) {
                    for (var n = -1, r = t ? t.length : 0, e = 0, u = []; ++n < r;) {
                        var o = t[n];
                        o && (u[e++] = o)
                    }
                    return u
                }, jt.concat = function() {
                    var t = arguments.length,
                        n = me(arguments[0]);
                    if (2 > t) return t ? or(n) : [];
                    for (var r = Array(t - 1); t--;) r[t - 1] = arguments[t];
                    for (var t = hn(r, 1), r = -1, e = n.length, u = -1, o = t.length, i = Array(e + o); ++r < e;) i[r] = n[r];
                    for (; ++u < o;) i[r++] = t[u];
                    return i
                }, jt.cond = function(t) {
                    var n = t ? t.length : 0,
                        e = Rr();
                    return t = n ? a(t, function(t) {
                        if ("function" != typeof t[1]) throw new vu("Expected a function");
                        return [e(t[0]), t[1]]
                    }) : [], je(function(e) {
                        for (var u = -1; ++u < n;) {
                            var o = t[u];
                            if (r(o[0], this, e)) return r(o[1], this, e)
                        }
                    })
                }, jt.conforms = function(t) {
                    return on(un(t, true))
                }, jt.constant = ou, jt.countBy = To, jt.create = function(t, n) {
                    var r = fn(t);
                    return n ? nn(r, n) : r
                }, jt.curry = de, jt.curryRight = ye, jt.debounce = be, jt.defaults = hi, jt.defaultsDeep = pi, jt.defer = Xo, jt.delay = ti, jt.difference = ko, jt.differenceBy = Eo,
                jt.differenceWith = Io, jt.drop = te, jt.dropRight = ne, jt.dropRightWhile = function(t, n) {
                    return t && t.length ? Gn(t, Rr(n, 3), true, true) : []
                }, jt.dropWhile = function(t, n) {
                    return t && t.length ? Gn(t, Rr(n, 3), true) : []
                }, jt.fill = function(t, n, r, e) {
                    var u = t ? t.length : 0;
                    if (!u) return [];
                    for (r && typeof r != "number" && Zr(t, n, r) && (r = 0, e = u), u = t.length, r = Ze(r), 0 > r && (r = -r > u ? 0 : u + r), e = e === q || e > u ? u : Ze(e), 0 > e && (e += u), e = r > e ? 0 : Te(e); e > r;) t[r++] = n;
                    return t
                }, jt.filter = function(t, n) {
                    return (oi(t) ? i : sn)(t, Rr(n, 3))
                }, jt.flatMap = function(t, n) {
                    return hn(pe(t, n), 1);
                }, jt.flatMapDeep = function(t, n) {
                    return hn(pe(t, n), V)
                }, jt.flatMapDepth = function(t, n, r) {
                    return r = r === q ? 1 : Ze(r), hn(pe(t, n), r)
                }, jt.flatten = function(t) {
                    return t && t.length ? hn(t, 1) : []
                }, jt.flattenDeep = function(t) {
                    return t && t.length ? hn(t, V) : []
                }, jt.flattenDepth = function(t, n) {
                    return t && t.length ? (n = n === q ? 1 : Ze(n), hn(t, n)) : []
                }, jt.flip = function(t) {
                    return kr(t, 512)
                }, jt.flow = Wi, jt.flowRight = Bi, jt.fromPairs = function(t) {
                    for (var n = -1, r = t ? t.length : 0, e = {}; ++n < r;) {
                        var u = t[n];
                        e[u[0]] = u[1]
                    }
                    return e
                }, jt.functions = function(t) {
                    return null == t ? [] : vn(t, He(t))
                }, jt.functionsIn = function(t) {
                    return null == t ? [] : vn(t, Qe(t))
                }, jt.groupBy = qo, jt.initial = function(t) {
                    return ne(t, 1)
                }, jt.intersection = So, jt.intersectionBy = Ro, jt.intersectionWith = Wo, jt.invert = _i, jt.invertBy = vi, jt.invokeMap = Vo, jt.iteratee = fu, jt.keyBy = Ko, jt.keys = He, jt.keysIn = Qe, jt.map = pe, jt.mapKeys = function(t, n) {
                    var r = {};
                    return n = Rr(n, 3), pn(t, function(t, e, u) {
                        r[n(t, e, u)] = t
                    }), r
                }, jt.mapValues = function(t, n) {
                    var r = {};
                    return n = Rr(n, 3), pn(t, function(t, e, u) {
                        r[e] = n(t, e, u)
                    }), r
                }, jt.matches = function(t) {
                    return In(un(t, true))
                }, jt.matchesProperty = function(t, n) {
                    return Sn(t, un(n, true))
                }, jt.memoize = xe, jt.merge = di, jt.mergeWith = yi, jt.method = Li, jt.methodOf = Ci, jt.mixin = cu, jt.negate = function(t) {
                    if (typeof t != "function") throw new vu("Expected a function");
                    return function() {
                        return !t.apply(this, arguments)
                    }
                }, jt.nthArg = function(t) {
                    return t = Ze(t), je(function(n) {
                        return Wn(n, t)
                    })
                }, jt.omit = bi, jt.omitBy = function(t, n) {
                    return n = Rr(n), Cn(t, function(t, r) {
                        return !n(t, r)
                    })
                }, jt.once = function(t) {
                    return ge(2, t)
                }, jt.orderBy = function(t, n, r, e) {
                    return null == t ? [] : (oi(n) || (n = null == n ? [] : [n]), r = e ? q : r, oi(r) || (r = null == r ? [] : [r]), Bn(t, n, r))
                }, jt.over = Mi, jt.overArgs = ni, jt.overEvery = zi, jt.overSome = Ui, jt.partial = ri, jt.partialRight = ei, jt.partition = Go, jt.pick = xi, jt.pickBy = function(t, n) {
                    return null == t ? {} : Cn(t, Rr(n))
                }, jt.property = lu, jt.propertyOf = function(t) {
                    return function(n) {
                        return null == t ? q : gn(t, n)
                    }
                }, jt.pull = Bo, jt.pullAll = ue, jt.pullAllBy = function(t, n, r) {
                    return t && t.length && n && n.length ? Un(t, n, Rr(r)) : t
                }, jt.pullAllWith = function(t, n, r) {
                    return t && t.length && n && n.length ? Un(t, n, q, r) : t;
                }, jt.pullAt = Lo, jt.range = Di, jt.rangeRight = $i, jt.rearg = ui, jt.reject = function(t, n) {
                    var r = oi(t) ? i : sn;
                    return n = Rr(n, 3), r(t, function(t, r, e) {
                        return !n(t, r, e)
                    })
                }, jt.remove = function(t, n) {
                    var r = [];
                    if (!t || !t.length) return r;
                    var e = -1,
                        u = [],
                        o = t.length;
                    for (n = Rr(n, 3); ++e < o;) {
                        var i = t[e];
                        n(i, e, t) && (r.push(i), u.push(e))
                    }
                    return Dn(t, u), r
                }, jt.rest = je, jt.reverse = oe, jt.sampleSize = _e, jt.set = function(t, n, r) {
                    return null == t ? t : Nn(t, n, r)
                }, jt.setWith = function(t, n, r, e) {
                    return e = typeof e == "function" ? e : q, null == t ? t : Nn(t, n, r, e)
                }, jt.shuffle = function(t) {
                    return _e(t, 4294967295)
                }, jt.slice = function(t, n, r) {
                    var e = t ? t.length : 0;
                    return e ? (r && typeof r != "number" && Zr(t, n, r) ? (n = 0, r = e) : (n = null == n ? 0 : Ze(n), r = r === q ? e : Ze(r)), Pn(t, n, r)) : []
                }, jt.sortBy = Jo, jt.sortedUniq = function(t) {
                    return t && t.length ? Vn(t) : []
                }, jt.sortedUniqBy = function(t, n) {
                    return t && t.length ? Vn(t, Rr(n)) : []
                }, jt.split = function(t, n, r) {
                    return r && typeof r != "number" && Zr(t, n, r) && (n = r = q), r = r === q ? 4294967295 : r >>> 0, r ? (t = Ke(t)) && (typeof n == "string" || null != n && !Ue(n)) && (n += "", "" == n && Bt.test(t)) ? tr(t.match(Rt), 0, r) : Yu.call(t, n, r) : [];
                }, jt.spread = function(t, n) {
                    if (typeof t != "function") throw new vu("Expected a function");
                    return n = n === q ? 0 : Tu(Ze(n), 0), je(function(e) {
                        var u = e[n];
                        return e = tr(e, 0, n), u && l(e, u), r(t, this, e)
                    })
                }, jt.tail = function(t) {
                    return te(t, 1)
                }, jt.take = function(t, n, r) {
                    return t && t.length ? (n = r || n === q ? 1 : Ze(n), Pn(t, 0, 0 > n ? 0 : n)) : []
                }, jt.takeRight = function(t, n, r) {
                    var e = t ? t.length : 0;
                    return e ? (n = r || n === q ? 1 : Ze(n), n = e - n, Pn(t, 0 > n ? 0 : n, e)) : []
                }, jt.takeRightWhile = function(t, n) {
                    return t && t.length ? Gn(t, Rr(n, 3), false, true) : []
                }, jt.takeWhile = function(t, n) {
                    return t && t.length ? Gn(t, Rr(n, 3)) : []
                }, jt.tap = function(t, n) {
                    return n(t), t
                }, jt.throttle = function(t, n, r) {
                    var e = true,
                        u = true;
                    if (typeof t != "function") throw new vu("Expected a function");
                    return Be(r) && (e = "leading" in r ? !!r.leading : e, u = "trailing" in r ? !!r.trailing : u), be(t, n, {
                        leading: e,
                        maxWait: n,
                        trailing: u
                    })
                }, jt.thru = ae, jt.toArray = Pe, jt.toPairs = Xe, jt.toPairsIn = tu, jt.toPath = function(t) {
                    return oi(t) ? a(t, Hr) : $e(t) ? [t] : or(Oo(t))
                }, jt.toPlainObject = Ve, jt.transform = function(t, n, r) {
                    var e = oi(t) || Fe(t);
                    if (n = Rr(n, 4), null == r)
                        if (e || Be(t)) {
                            var o = t.constructor;
                            r = e ? oi(t) ? new o : [] : Se(o) ? fn(Fu(Object(t))) : {}
                        } else r = {};
                    return (e ? u : pn)(t, function(t, e, u) {
                        return n(r, t, e, u)
                    }), r
                }, jt.unary = function(t) {
                    return ve(t, 1)
                }, jt.union = Co, jt.unionBy = Mo, jt.unionWith = zo, jt.uniq = function(t) {
                    return t && t.length ? Kn(t) : []
                }, jt.uniqBy = function(t, n) {
                    return t && t.length ? Kn(t, Rr(n)) : []
                }, jt.uniqWith = function(t, n) {
                    return t && t.length ? Kn(t, q, n) : []
                }, jt.unset = function(t, n) {
                    var r;
                    if (null == t) r = true;
                    else {
                        r = t;
                        var e = n,
                            e = Tr(e, r) ? [e] : Xn(e);
                        r = Yr(r, e), e = ee(e), r = null != r && Je(r, e) ? delete r[e] : true;
                    }
                    return r
                }, jt.unzip = ie, jt.unzipWith = fe, jt.update = function(t, n, r) {
                    return null == t ? t : Nn(t, n, (typeof r == "function" ? r : iu)(gn(t, n)), void 0)
                }, jt.updateWith = function(t, n, r, e) {
                    return e = typeof e == "function" ? e : q, null != t && (t = Nn(t, n, (typeof r == "function" ? r : iu)(gn(t, n)), e)), t
                }, jt.values = nu, jt.valuesIn = function(t) {
                    return null == t ? [] : k(t, Qe(t))
                }, jt.without = Uo, jt.words = uu, jt.wrap = function(t, n) {
                    return n = null == n ? iu : n, ri(n, t)
                }, jt.xor = Do, jt.xorBy = $o, jt.xorWith = Fo, jt.zip = No, jt.zipObject = function(t, n) {
                    return Hn(t || [], n || [], Xt);
                }, jt.zipObjectDeep = function(t, n) {
                    return Hn(t || [], n || [], Nn)
                }, jt.zipWith = Po, jt.entries = Xe, jt.entriesIn = tu, jt.extend = ci, jt.extendWith = ai, cu(jt, jt), jt.add = Fi, jt.attempt = Si, jt.camelCase = ji, jt.capitalize = ru, jt.ceil = Ni, jt.clamp = function(t, n, r) {
                    return r === q && (r = n, n = q), r !== q && (r = qe(r), r = r === r ? r : 0), n !== q && (n = qe(n), n = n === n ? n : 0), en(qe(t), n, r)
                }, jt.clone = function(t) {
                    return un(t, false, true)
                }, jt.cloneDeep = function(t) {
                    return un(t, true, true)
                }, jt.cloneDeepWith = function(t, n) {
                    return un(t, true, true, n)
                }, jt.cloneWith = function(t, n) {
                    return un(t, false, true, n);
                }, jt.deburr = eu, jt.divide = Pi, jt.endsWith = function(t, n, r) {
                    t = Ke(t), n = typeof n == "string" ? n : n + "";
                    var e = t.length;
                    return r = r === q ? e : en(Ze(r), 0, e), r -= n.length, r >= 0 && t.indexOf(n, r) == r
                }, jt.eq = we, jt.escape = function(t) {
                    return (t = Ke(t)) && tt.test(t) ? t.replace(Q, L) : t
                }, jt.escapeRegExp = function(t) {
                    return (t = Ke(t)) && ct.test(t) ? t.replace(ft, "\\$&") : t
                }, jt.every = function(t, n, r) {
                    var e = oi(t) ? o : ln;
                    return r && Zr(t, n, r) && (n = q), e(t, Rr(n, 3))
                }, jt.find = function(t, n) {
                    if (n = Rr(n, 3), oi(t)) {
                        var r = g(t, n);
                        return r > -1 ? t[r] : q
                    }
                    return v(t, n, _o);
                }, jt.findIndex = function(t, n) {
                    return t && t.length ? g(t, Rr(n, 3)) : -1
                }, jt.findKey = function(t, n) {
                    return v(t, Rr(n, 3), pn, true)
                }, jt.findLast = function(t, n) {
                    if (n = Rr(n, 3), oi(t)) {
                        var r = g(t, n, true);
                        return r > -1 ? t[r] : q
                    }
                    return v(t, n, vo)
                }, jt.findLastIndex = function(t, n) {
                    return t && t.length ? g(t, Rr(n, 3), true) : -1
                }, jt.findLastKey = function(t, n) {
                    return v(t, Rr(n, 3), _n, true)
                }, jt.floor = Zi, jt.forEach = se, jt.forEachRight = he, jt.forIn = function(t, n) {
                    return null == t ? t : go(t, Rr(n), Qe)
                }, jt.forInRight = function(t, n) {
                    return null == t ? t : yo(t, Rr(n), Qe);
                }, jt.forOwn = function(t, n) {
                    return t && pn(t, Rr(n))
                }, jt.forOwnRight = function(t, n) {
                    return t && _n(t, Rr(n))
                }, jt.get = Ge, jt.gt = Ae, jt.gte = function(t, n) {
                    return t >= n
                }, jt.has = Je, jt.hasIn = Ye, jt.head = re, jt.identity = iu, jt.includes = function(t, n, r, e) {
                    return t = ke(t) ? t : nu(t), r = r && !e ? Ze(r) : 0, e = t.length, 0 > r && (r = Tu(e + r, 0)), De(t) ? e >= r && -1 < t.indexOf(n, r) : !!e && -1 < d(t, n, r)
                }, jt.indexOf = function(t, n, r) {
                    var e = t ? t.length : 0;
                    return e ? (r = Ze(r), 0 > r && (r = Tu(e + r, 0)), d(t, n, r)) : -1
                }, jt.inRange = function(t, n, r) {
                    return n = qe(n) || 0, r === q ? (r = n,
                        n = 0) : r = qe(r) || 0, t = qe(t), t >= qu(n, r) && t < Tu(n, r)
                }, jt.invoke = gi, jt.isArguments = Oe, jt.isArray = oi, jt.isArrayBuffer = function(t) {
                    return Le(t) && "[object ArrayBuffer]" == wu.call(t)
                }, jt.isArrayLike = ke, jt.isArrayLikeObject = Ee, jt.isBoolean = function(t) {
                    return true === t || false === t || Le(t) && "[object Boolean]" == wu.call(t)
                }, jt.isBuffer = ii, jt.isDate = function(t) {
                    return Le(t) && "[object Date]" == wu.call(t)
                }, jt.isElement = function(t) {
                    return !!t && 1 === t.nodeType && Le(t) && !ze(t)
                }, jt.isEmpty = function(t) {
                    if (ke(t) && (oi(t) || De(t) || Se(t.splice) || Oe(t) || ii(t))) return !t.length;
                    if (Le(t)) {
                        var n = Mr(t);
                        if ("[object Map]" == n || "[object Set]" == n) return !t.size
                    }
                    for (var r in t)
                        if (xu.call(t, r)) return false;
                    return !(uo && He(t).length)
                }, jt.isEqual = function(t, n) {
                    return wn(t, n)
                }, jt.isEqualWith = function(t, n, r) {
                    var e = (r = typeof r == "function" ? r : q) ? r(t, n) : q;
                    return e === q ? wn(t, n, r) : !!e
                }, jt.isError = Ie, jt.isFinite = function(t) {
                    return typeof t == "number" && Nu(t)
                }, jt.isFunction = Se, jt.isInteger = Re, jt.isLength = We, jt.isMap = function(t) {
                    return Le(t) && "[object Map]" == Mr(t)
                }, jt.isMatch = function(t, n) {
                    return t === n || An(t, n, Wr(n));
                }, jt.isMatchWith = function(t, n, r) {
                    return r = typeof r == "function" ? r : q, An(t, n, Wr(n), r)
                }, jt.isNaN = function(t) {
                    return Me(t) && t != +t
                }, jt.isNative = Ce, jt.isNil = function(t) {
                    return null == t
                }, jt.isNull = function(t) {
                    return null === t
                }, jt.isNumber = Me, jt.isObject = Be, jt.isObjectLike = Le, jt.isPlainObject = ze, jt.isRegExp = Ue, jt.isSafeInteger = function(t) {
                    return Re(t) && t >= -9007199254740991 && 9007199254740991 >= t
                }, jt.isSet = function(t) {
                    return Le(t) && "[object Set]" == Mr(t)
                }, jt.isString = De, jt.isSymbol = $e, jt.isTypedArray = Fe, jt.isUndefined = function(t) {
                    return t === q
                }, jt.isWeakMap = function(t) {
                    return Le(t) && "[object WeakMap]" == Mr(t)
                }, jt.isWeakSet = function(t) {
                    return Le(t) && "[object WeakSet]" == wu.call(t)
                }, jt.join = function(t, n) {
                    return t ? Pu.call(t, n) : ""
                }, jt.kebabCase = mi, jt.last = ee, jt.lastIndexOf = function(t, n, r) {
                    var e = t ? t.length : 0;
                    if (!e) return -1;
                    var u = e;
                    if (r !== q && (u = Ze(r), u = (0 > u ? Tu(e + u, 0) : qu(u, e - 1)) + 1), n !== n) return M(t, u, true);
                    for (; u--;)
                        if (t[u] === n) return u;
                    return -1
                }, jt.lowerCase = wi, jt.lowerFirst = Ai, jt.lt = Ne, jt.lte = function(t, n) {
                    return n >= t
                }, jt.max = function(t) {
                    return t && t.length ? _(t, iu, Ae) : q
                }, jt.maxBy = function(t, n) {
                    return t && t.length ? _(t, Rr(n), Ae) : q
                }, jt.mean = function(t) {
                    return b(t, iu)
                }, jt.meanBy = function(t, n) {
                    return b(t, Rr(n))
                }, jt.min = function(t) {
                    return t && t.length ? _(t, iu, Ne) : q
                }, jt.minBy = function(t, n) {
                    return t && t.length ? _(t, Rr(n), Ne) : q
                }, jt.multiply = Ti, jt.nth = function(t, n) {
                    return t && t.length ? Wn(t, Ze(n)) : q
                }, jt.noConflict = function() {
                    return Yt._ === this && (Yt._ = Au), this
                }, jt.noop = au, jt.now = Yo, jt.pad = function(t, n, r) {
                    t = Ke(t);
                    var e = (n = Ze(n)) ? P(t) : 0;
                    return n && n > e ? (n = (n - e) / 2,
                        jr($u(n), r) + t + jr(Du(n), r)) : t
                }, jt.padEnd = function(t, n, r) {
                    t = Ke(t);
                    var e = (n = Ze(n)) ? P(t) : 0;
                    return n && n > e ? t + jr(n - e, r) : t
                }, jt.padStart = function(t, n, r) {
                    t = Ke(t);
                    var e = (n = Ze(n)) ? P(t) : 0;
                    return n && n > e ? jr(n - e, r) + t : t
                }, jt.parseInt = function(t, n, r) {
                    return r || null == n ? n = 0 : n && (n = +n), t = Ke(t).replace(at, ""), Vu(t, n || (gt.test(t) ? 16 : 10))
                }, jt.random = function(t, n, r) {
                    if (r && typeof r != "boolean" && Zr(t, n, r) && (n = r = q), r === q && (typeof n == "boolean" ? (r = n, n = q) : typeof t == "boolean" && (r = t, t = q)), t === q && n === q ? (t = 0, n = 1) : (t = qe(t) || 0, n === q ? (n = t,
                            t = 0) : n = qe(n) || 0), t > n) {
                        var e = t;
                        t = n, n = e
                    }
                    return r || t % 1 || n % 1 ? (r = Ku(), qu(t + r * (n - t + Pt("1e-" + ((r + "").length - 1))), n)) : $n(t, n)
                }, jt.reduce = function(t, n, r) {
                    var e = oi(t) ? s : x,
                        u = 3 > arguments.length;
                    return e(t, Rr(n, 4), r, u, _o)
                }, jt.reduceRight = function(t, n, r) {
                    var e = oi(t) ? h : x,
                        u = 3 > arguments.length;
                    return e(t, Rr(n, 4), r, u, vo)
                }, jt.repeat = function(t, n, r) {
                    return n = (r ? Zr(t, n, r) : n === q) ? 1 : Ze(n), Fn(Ke(t), n)
                }, jt.replace = function() {
                    var t = arguments,
                        n = Ke(t[0]);
                    return 3 > t.length ? n : Gu.call(n, t[1], t[2])
                }, jt.result = function(t, n, r) {
                    n = Tr(n, t) ? [n] : Xn(n);
                    var e = -1,
                        u = n.length;
                    for (u || (t = q, u = 1); ++e < u;) {
                        var o = null == t ? q : t[n[e]];
                        o === q && (e = u, o = r), t = Se(o) ? o.call(t) : o
                    }
                    return t
                }, jt.round = qi, jt.runInContext = T, jt.sample = function(t) {
                    t = ke(t) ? t : nu(t);
                    var n = t.length;
                    return n > 0 ? t[$n(0, n - 1)] : q
                }, jt.size = function(t) {
                    if (null == t) return 0;
                    if (ke(t)) {
                        var n = t.length;
                        return n && De(t) ? P(t) : n
                    }
                    return Le(t) && (n = Mr(t), "[object Map]" == n || "[object Set]" == n) ? t.size : He(t).length
                }, jt.snakeCase = Oi, jt.some = function(t, n, r) {
                    var e = oi(t) ? p : Zn;
                    return r && Zr(t, n, r) && (n = q), e(t, Rr(n, 3))
                }, jt.sortedIndex = function(t, n) {
                    return Tn(t, n)
                }, jt.sortedIndexBy = function(t, n, r) {
                    return qn(t, n, Rr(r))
                }, jt.sortedIndexOf = function(t, n) {
                    var r = t ? t.length : 0;
                    if (r) {
                        var e = Tn(t, n);
                        if (r > e && we(t[e], n)) return e
                    }
                    return -1
                }, jt.sortedLastIndex = function(t, n) {
                    return Tn(t, n, true)
                }, jt.sortedLastIndexBy = function(t, n, r) {
                    return qn(t, n, Rr(r), true)
                }, jt.sortedLastIndexOf = function(t, n) {
                    if (t && t.length) {
                        var r = Tn(t, n, true) - 1;
                        if (we(t[r], n)) return r
                    }
                    return -1
                }, jt.startCase = ki, jt.startsWith = function(t, n, r) {
                    return t = Ke(t), r = en(Ze(r), 0, t.length), t.lastIndexOf(n, r) == r;
                }, jt.subtract = Vi, jt.sum = function(t) {
                    return t && t.length ? m(t, iu) : 0
                }, jt.sumBy = function(t, n) {
                    return t && t.length ? m(t, Rr(n)) : 0
                }, jt.template = function(t, n, r) {
                    var e = jt.templateSettings;
                    r && Zr(t, n, r) && (n = q), t = Ke(t), n = ai({}, n, e, Jt), r = ai({}, n.imports, e.imports, Jt);
                    var u, o, i = He(r),
                        f = k(r, i),
                        c = 0;
                    r = n.interpolate || wt;
                    var a = "__p+='";
                    r = _u((n.escape || wt).source + "|" + r.source + "|" + (r === et ? _t : wt).source + "|" + (n.evaluate || wt).source + "|$", "g");
                    var l = "sourceURL" in n ? "//# sourceURL=" + n.sourceURL + "\n" : "";
                    if (t.replace(r, function(n, r, e, i, f, l) {
                            return e || (e = i), a += t.slice(c, l).replace(At, C), r && (u = true, a += "'+__e(" + r + ")+'"), f && (o = true, a += "';" + f + ";\n__p+='"), e && (a += "'+((__t=(" + e + "))==null?'':__t)+'"), c = l + n.length, n
                        }), a += "';", (n = n.variable) || (a = "with(obj){" + a + "}"), a = (o ? a.replace(G, "") : a).replace(J, "$1").replace(Y, "$1;"), a = "function(" + (n || "obj") + "){" + (n ? "" : "obj||(obj={});") + "var __t,__p=''" + (u ? ",__e=_.escape" : "") + (o ? ",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}" : ";") + a + "return __p}", n = Si(function() {
                            return Function(i, l + "return " + a).apply(q, f);
                        }), n.source = a, Ie(n)) throw n;
                    return n
                }, jt.times = function(t, n) {
                    if (t = Ze(t), 1 > t || t > 9007199254740991) return [];
                    var r = 4294967295,
                        e = qu(t, 4294967295);
                    for (n = Rr(n), t -= 4294967295, e = w(e, n); ++r < t;) n(r);
                    return e
                }, jt.toInteger = Ze, jt.toLength = Te, jt.toLower = function(t) {
                    return Ke(t).toLowerCase()
                }, jt.toNumber = qe, jt.toSafeInteger = function(t) {
                    return en(Ze(t), -9007199254740991, 9007199254740991)
                }, jt.toString = Ke, jt.toUpper = function(t) {
                    return Ke(t).toUpperCase()
                }, jt.trim = function(t, n, r) {
                    return (t = Ke(t)) ? r || n === q ? t.replace(at, "") : (n += "") ? (t = t.match(Rt),
                        n = n.match(Rt), tr(t, E(t, n), I(t, n) + 1).join("")) : t : t
                }, jt.trimEnd = function(t, n, r) {
                    return (t = Ke(t)) ? r || n === q ? t.replace(st, "") : (n += "") ? (t = t.match(Rt), n = I(t, n.match(Rt)) + 1, tr(t, 0, n).join("")) : t : t
                }, jt.trimStart = function(t, n, r) {
                    return (t = Ke(t)) ? r || n === q ? t.replace(lt, "") : (n += "") ? (t = t.match(Rt), n = E(t, n.match(Rt)), tr(t, n).join("")) : t : t
                }, jt.truncate = function(t, n) {
                    var r = 30,
                        e = "...";
                    if (Be(n)) var u = "separator" in n ? n.separator : u,
                        r = "length" in n ? Ze(n.length) : r,
                        e = "omission" in n ? Ke(n.omission) : e;
                    t = Ke(t);
                    var o = t.length;
                    if (Bt.test(t)) var i = t.match(Rt),
                        o = i.length;
                    if (r >= o) return t;
                    if (o = r - P(e), 1 > o) return e;
                    if (r = i ? tr(i, 0, o).join("") : t.slice(0, o), u === q) return r + e;
                    if (i && (o += r.length - o), Ue(u)) {
                        if (t.slice(o).search(u)) {
                            var f = r;
                            for (u.global || (u = _u(u.source, Ke(vt.exec(u)) + "g")), u.lastIndex = 0; i = u.exec(f);) var c = i.index;
                            r = r.slice(0, c === q ? o : c)
                        }
                    } else t.indexOf(u, o) != o && (u = r.lastIndexOf(u), u > -1 && (r = r.slice(0, u)));
                    return r + e
                }, jt.unescape = function(t) {
                    return (t = Ke(t)) && X.test(t) ? t.replace(H, Z) : t
                }, jt.uniqueId = function(t) {
                    var n = ++ju;
                    return Ke(t) + n
                }, jt.upperCase = Ei, jt.upperFirst = Ii,
                jt.each = se, jt.eachRight = he, jt.first = re, cu(jt, function() {
                    var t = {};
                    return pn(jt, function(n, r) {
                        xu.call(jt.prototype, r) || (t[r] = n)
                    }), t
                }(), {
                    chain: false
                }), jt.VERSION = "4.11.0", u("bind bindKey curry curryRight partial partialRight".split(" "), function(t) {
                    jt[t].placeholder = jt
                }), u(["drop", "take"], function(t, n) {
                    Et.prototype[t] = function(r) {
                        var e = this.__filtered__;
                        if (e && !n) return new Et(this);
                        r = r === q ? 1 : Tu(Ze(r), 0);
                        var u = this.clone();
                        return e ? u.__takeCount__ = qu(r, u.__takeCount__) : u.__views__.push({
                            size: qu(r, 4294967295),
                            type: t + (0 > u.__dir__ ? "Right" : "")
                        }), u
                    }, Et.prototype[t + "Right"] = function(n) {
                        return this.reverse()[t](n).reverse()
                    }
                }), u(["filter", "map", "takeWhile"], function(t, n) {
                    var r = n + 1,
                        e = 1 == r || 3 == r;
                    Et.prototype[t] = function(t) {
                        var n = this.clone();
                        return n.__iteratees__.push({
                            iteratee: Rr(t, 3),
                            type: r
                        }), n.__filtered__ = n.__filtered__ || e, n
                    }
                }), u(["head", "last"], function(t, n) {
                    var r = "take" + (n ? "Right" : "");
                    Et.prototype[t] = function() {
                        return this[r](1).value()[0]
                    }
                }), u(["initial", "tail"], function(t, n) {
                    var r = "drop" + (n ? "" : "Right");
                    Et.prototype[t] = function() {
                        return this.__filtered__ ? new Et(this) : this[r](1)
                    }
                }), Et.prototype.compact = function() {
                    return this.filter(iu)
                }, Et.prototype.find = function(t) {
                    return this.filter(t).head()
                }, Et.prototype.findLast = function(t) {
                    return this.reverse().find(t)
                }, Et.prototype.invokeMap = je(function(t, n) {
                    return typeof t == "function" ? new Et(this) : this.map(function(r) {
                        return mn(r, t, n)
                    })
                }), Et.prototype.reject = function(t) {
                    return t = Rr(t, 3), this.filter(function(n) {
                        return !t(n)
                    })
                }, Et.prototype.slice = function(t, n) {
                    t = Ze(t);
                    var r = this;
                    return r.__filtered__ && (t > 0 || 0 > n) ? new Et(r) : (0 > t ? r = r.takeRight(-t) : t && (r = r.drop(t)), n !== q && (n = Ze(n), r = 0 > n ? r.dropRight(-n) : r.take(n - t)), r)
                }, Et.prototype.takeRightWhile = function(t) {
                    return this.reverse().takeWhile(t).reverse()
                }, Et.prototype.toArray = function() {
                    return this.take(4294967295)
                }, pn(Et.prototype, function(t, n) {
                    var r = /^(?:filter|find|map|reject)|While$/.test(n),
                        e = /^(?:head|last)$/.test(n),
                        u = jt[e ? "take" + ("last" == n ? "Right" : "") : n],
                        o = e || /^find/.test(n);
                    u && (jt.prototype[n] = function() {
                        function n(t) {
                            return t = u.apply(jt, l([t], f)), e && h ? t[0] : t
                        }
                        var i = this.__wrapped__,
                            f = e ? [1] : arguments,
                            c = i instanceof Et,
                            a = f[0],
                            s = c || oi(i);
                        s && r && typeof a == "function" && 1 != a.length && (c = s = false);
                        var h = this.__chain__,
                            p = !!this.__actions__.length,
                            a = o && !h,
                            c = c && !p;
                        return !o && s ? (i = c ? i : new Et(this), i = t.apply(i, f), i.__actions__.push({
                            func: ae,
                            args: [n],
                            thisArg: q
                        }), new kt(i, h)) : a && c ? t.apply(this, f) : (i = this.thru(n), a ? e ? i.value()[0] : i.value() : i)
                    })
                }), u("pop push shift sort splice unshift".split(" "), function(t) {
                    var n = gu[t],
                        r = /^(?:push|sort|unshift)$/.test(t) ? "tap" : "thru",
                        e = /^(?:pop|shift)$/.test(t);
                    jt.prototype[t] = function() {
                        var t = arguments;
                        if (e && !this.__chain__) {
                            var u = this.value();
                            return n.apply(oi(u) ? u : [], t)
                        }
                        return this[r](function(r) {
                            return n.apply(oi(r) ? r : [], t)
                        })
                    }
                }), pn(Et.prototype, function(t, n) {
                    var r = jt[n];
                    if (r) {
                        var e = r.name + "";
                        (oo[e] || (oo[e] = [])).push({
                            name: n,
                            func: r
                        })
                    }
                }), oo[yr(q, 2).name] = [{
                    name: "wrapper",
                    func: q
                }], Et.prototype.clone = function() {
                    var t = new Et(this.__wrapped__);
                    return t.__actions__ = or(this.__actions__), t.__dir__ = this.__dir__, t.__filtered__ = this.__filtered__, t.__iteratees__ = or(this.__iteratees__),
                        t.__takeCount__ = this.__takeCount__, t.__views__ = or(this.__views__), t
                }, Et.prototype.reverse = function() {
                    if (this.__filtered__) {
                        var t = new Et(this);
                        t.__dir__ = -1, t.__filtered__ = true
                    } else t = this.clone(), t.__dir__ *= -1;
                    return t
                }, Et.prototype.value = function() {
                    var t, n = this.__wrapped__.value(),
                        r = this.__dir__,
                        e = oi(n),
                        u = 0 > r,
                        o = e ? n.length : 0;
                    t = o;
                    for (var i = this.__views__, f = 0, c = -1, a = i.length; ++c < a;) {
                        var l = i[c],
                            s = l.size;
                        switch (l.type) {
                            case "drop":
                                f += s;
                                break;
                            case "dropRight":
                                t -= s;
                                break;
                            case "take":
                                t = qu(t, f + s);
                                break;
                            case "takeRight":
                                f = Tu(f, t - s)
                        }
                    }
                    if (t = {
                            start: f,
                            end: t
                        }, i = t.start, f = t.end, t = f - i, u = u ? f : i - 1, i = this.__iteratees__, f = i.length, c = 0, a = qu(t, this.__takeCount__), !e || 200 > o || o == t && a == t) return Jn(n, this.__actions__);
                    e = [];
                    t: for (; t-- && a > c;) {
                        for (u += r, o = -1, l = n[u]; ++o < f;) {
                            var h = i[o],
                                s = h.type,
                                h = (0, h.iteratee)(l);
                            if (2 == s) l = h;
                            else if (!h) {
                                if (1 == s) continue t;
                                break t
                            }
                        }
                        e[c++] = l
                    }
                    return e
                }, jt.prototype.at = Zo, jt.prototype.chain = function() {
                    return ce(this)
                }, jt.prototype.commit = function() {
                    return new kt(this.value(), this.__chain__)
                }, jt.prototype.next = function() {
                    this.__values__ === q && (this.__values__ = Pe(this.value()));
                    var t = this.__index__ >= this.__values__.length,
                        n = t ? q : this.__values__[this.__index__++];
                    return {
                        done: t,
                        value: n
                    }
                }, jt.prototype.plant = function(t) {
                    for (var n, r = this; r instanceof Ot;) {
                        var e = Xr(r);
                        e.__index__ = 0, e.__values__ = q, n ? u.__wrapped__ = e : n = e;
                        var u = e,
                            r = r.__wrapped__
                    }
                    return u.__wrapped__ = t, n
                }, jt.prototype.reverse = function() {
                    var t = this.__wrapped__;
                    return t instanceof Et ? (this.__actions__.length && (t = new Et(this)), t = t.reverse(), t.__actions__.push({
                        func: ae,
                        args: [oe],
                        thisArg: q
                    }), new kt(t, this.__chain__)) : this.thru(oe)
                }, jt.prototype.toJSON = jt.prototype.valueOf = jt.prototype.value = function() {
                    return Jn(this.__wrapped__, this.__actions__)
                }, Lu && (jt.prototype[Lu] = le), jt
        }
        var q, V = 1 / 0,
            K = NaN,
            G = /\b__p\+='';/g,
            J = /\b(__p\+=)''\+/g,
            Y = /(__e\(.*?\)|\b__t\))\+'';/g,
            H = /&(?:amp|lt|gt|quot|#39|#96);/g,
            Q = /[&<>"'`]/g,
            X = RegExp(H.source),
            tt = RegExp(Q.source),
            nt = /<%-([\s\S]+?)%>/g,
            rt = /<%([\s\S]+?)%>/g,
            et = /<%=([\s\S]+?)%>/g,
            ut = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
            ot = /^\w*$/,
            it = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g,
            ft = /[\\^$.*+?()[\]{}|]/g,
            ct = RegExp(ft.source),
            at = /^\s+|\s+$/g,
            lt = /^\s+/,
            st = /\s+$/,
            ht = /[a-zA-Z0-9]+/g,
            pt = /\\(\\)?/g,
            _t = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,
            vt = /\w*$/,
            gt = /^0x/i,
            dt = /^[-+]0x[0-9a-f]+$/i,
            yt = /^0b[01]+$/i,
            bt = /^\[object .+?Constructor\]$/,
            xt = /^0o[0-7]+$/i,
            jt = /^(?:0|[1-9]\d*)$/,
            mt = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,
            wt = /($^)/,
            At = /['\n\r\u2028\u2029\\]/g,
            Ot = "[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?)*",
            kt = "(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])" + Ot,
            Et = "(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]?|[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",
            It = RegExp("['\u2019]", "g"),
            St = RegExp("[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]", "g"),
            Rt = RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|" + Et + Ot, "g"),
            Wt = RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?:['\u2019](?:d|ll|m|re|s|t|ve))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:d|ll|m|re|s|t|ve))?|[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?|\\d+", kt].join("|"), "g"),
            Bt = RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0\\ufe0e\\ufe0f]"),
            Lt = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,
            Ct = "Array Buffer DataView Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Promise Reflect RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),
            Mt = {};
        Mt["[object Float32Array]"] = Mt["[object Float64Array]"] = Mt["[object Int8Array]"] = Mt["[object Int16Array]"] = Mt["[object Int32Array]"] = Mt["[object Uint8Array]"] = Mt["[object Uint8ClampedArray]"] = Mt["[object Uint16Array]"] = Mt["[object Uint32Array]"] = true, Mt["[object Arguments]"] = Mt["[object Array]"] = Mt["[object ArrayBuffer]"] = Mt["[object Boolean]"] = Mt["[object DataView]"] = Mt["[object Date]"] = Mt["[object Error]"] = Mt["[object Function]"] = Mt["[object Map]"] = Mt["[object Number]"] = Mt["[object Object]"] = Mt["[object RegExp]"] = Mt["[object Set]"] = Mt["[object String]"] = Mt["[object WeakMap]"] = false;
        var zt = {};
        zt["[object Arguments]"] = zt["[object Array]"] = zt["[object ArrayBuffer]"] = zt["[object DataView]"] = zt["[object Boolean]"] = zt["[object Date]"] = zt["[object Float32Array]"] = zt["[object Float64Array]"] = zt["[object Int8Array]"] = zt["[object Int16Array]"] = zt["[object Int32Array]"] = zt["[object Map]"] = zt["[object Number]"] = zt["[object Object]"] = zt["[object RegExp]"] = zt["[object Set]"] = zt["[object String]"] = zt["[object Symbol]"] = zt["[object Uint8Array]"] = zt["[object Uint8ClampedArray]"] = zt["[object Uint16Array]"] = zt["[object Uint32Array]"] = true,
            zt["[object Error]"] = zt["[object Function]"] = zt["[object WeakMap]"] = false;
        var Ut = {
                "\xc0": "A",
                "\xc1": "A",
                "\xc2": "A",
                "\xc3": "A",
                "\xc4": "A",
                "\xc5": "A",
                "\xe0": "a",
                "\xe1": "a",
                "\xe2": "a",
                "\xe3": "a",
                "\xe4": "a",
                "\xe5": "a",
                "\xc7": "C",
                "\xe7": "c",
                "\xd0": "D",
                "\xf0": "d",
                "\xc8": "E",
                "\xc9": "E",
                "\xca": "E",
                "\xcb": "E",
                "\xe8": "e",
                "\xe9": "e",
                "\xea": "e",
                "\xeb": "e",
                "\xcc": "I",
                "\xcd": "I",
                "\xce": "I",
                "\xcf": "I",
                "\xec": "i",
                "\xed": "i",
                "\xee": "i",
                "\xef": "i",
                "\xd1": "N",
                "\xf1": "n",
                "\xd2": "O",
                "\xd3": "O",
                "\xd4": "O",
                "\xd5": "O",
                "\xd6": "O",
                "\xd8": "O",
                "\xf2": "o",
                "\xf3": "o",
                "\xf4": "o",
                "\xf5": "o",
                "\xf6": "o",
                "\xf8": "o",
                "\xd9": "U",
                "\xda": "U",
                "\xdb": "U",
                "\xdc": "U",
                "\xf9": "u",
                "\xfa": "u",
                "\xfb": "u",
                "\xfc": "u",
                "\xdd": "Y",
                "\xfd": "y",
                "\xff": "y",
                "\xc6": "Ae",
                "\xe6": "ae",
                "\xde": "Th",
                "\xfe": "th",
                "\xdf": "ss"
            },
            Dt = {
                "&": "&amp;",
                "<": "&lt;",
                ">": "&gt;",
                '"': "&quot;",
                "'": "&#39;",
                "`": "&#96;"
            },
            $t = {
                "&amp;": "&",
                "&lt;": "<",
                "&gt;": ">",
                "&quot;": '"',
                "&#39;": "'",
                "&#96;": "`"
            },
            Ft = {
                "function": true,
                object: true
            },
            Nt = {
                "\\": "\\",
                "'": "'",
                "\n": "n",
                "\r": "r",
                "\u2028": "u2028",
                "\u2029": "u2029"
            },
            Pt = parseFloat,
            Zt = parseInt,
            Tt = Ft[typeof exports] && exports && !exports.nodeType ? exports : q,
            qt = Ft[typeof module] && module && !module.nodeType ? module : q,
            Vt = qt && qt.exports === Tt ? Tt : q,
            Kt = S(Ft[typeof self] && self),
            Gt = S(Ft[typeof window] && window),
            Jt = S(Ft[typeof this] && this),
            Yt = S(Tt && qt && typeof global == "object" && global) || Gt !== (Jt && Jt.window) && Gt || Kt || Jt || Function("return this")(),
            Ht = T();
        (Gt || Kt || {})._ = Ht, typeof define == "function" && typeof define.amd == "object" && define.amd ? define(function() {
            return Ht
        }) : Tt && qt ? (Vt && ((qt.exports = Ht)._ = Ht),
            Tt._ = Ht) : Yt._ = Ht
    }).call(this);
    /*! RESOURCE: /scripts/libs/ocLazyLoad.min.js */
    /**
     * oclazyload - Load modules on demand (lazy load) with angularJS
     * @version v1.0.9
     * @link https://github.com/ocombe/ocLazyLoad
     * @license MIT
     * @author Olivier Combe <olivier.combe@gmail.com>
     */
    ! function(e, n) {
        "use strict";
        var r = ["ng", "oc.lazyLoad"],
            o = {},
            t = [],
            i = [],
            a = [],
            s = [],
            u = e.noop,
            c = {},
            l = [],
            d = e.module("oc.lazyLoad", ["ng"]);
        d.provider("$ocLazyLoad", ["$controllerProvider", "$provide", "$compileProvider", "$filterProvider", "$injector", "$animateProvider", function(d, f, p, m, v, y) {
            function L(n, o, t) {
                if (o) {
                    var i, s, d, f = [];
                    for (i = o.length - 1; i >= 0; i--)
                        if (s = o[i], e.isString(s) || (s = E(s)), s && -1 === l.indexOf(s) && (!w[s] || -1 !== a.indexOf(s))) {
                            var h = -1 === r.indexOf(s);
                            if (d = g(s), h && (r.push(s), L(n, d.requires, t)), d._runBlocks.length > 0)
                                for (c[s] = []; d._runBlocks.length > 0;) c[s].push(d._runBlocks.shift());
                            e.isDefined(c[s]) && (h || t.rerun) && (f = f.concat(c[s])), j(n, d._invokeQueue, s, t.reconfig), j(n, d._configBlocks, s, t.reconfig), u(h ? "ocLazyLoad.moduleLoaded" : "ocLazyLoad.moduleReloaded", s), o.pop(), l.push(s)
                        }
                    var p = n.getInstanceInjector();
                    e.forEach(f, function(e) {
                        p.invoke(e)
                    })
                }
            }
    
            function $(n, r) {
                function t(n, r) {
                    var o, t = !0;
                    return r.length && (o = i(n), e.forEach(r, function(e) {
                        t = t && i(e) !== o
                    })), t
                }
    
                function i(n) {
                    return e.isArray(n) ? M(n.toString()) : e.isObject(n) ? M(S(n)) : e.isDefined(n) && null !== n ? M(n.toString()) : n
                }
                var a = n[2][0],
                    s = n[1],
                    c = !1;
                e.isUndefined(o[r]) && (o[r] = {}), e.isUndefined(o[r][s]) && (o[r][s] = {});
                var l = function(e, n) {
                    o[r][s].hasOwnProperty(e) || (o[r][s][e] = []), t(n, o[r][s][e]) && (c = !0, o[r][s][e].push(n), u("ocLazyLoad.componentLoaded", [r, s, e]))
                };
                if (e.isString(a)) l(a, n[2][1]);
                else {
                    if (!e.isObject(a)) return !1;
                    e.forEach(a, function(n, r) {
                        e.isString(n) ? l(n, a[1]) : l(r, n)
                    })
                }
                return c
            }
    
            function j(n, r, o, i) {
                if (r) {
                    var a, s, u, c;
                    for (a = 0, s = r.length; s > a; a++)
                        if (u = r[a], e.isArray(u)) {
                            if (null !== n) {
                                if (!n.hasOwnProperty(u[0])) throw new Error("unsupported provider " + u[0]);
                                c = n[u[0]]
                            }
                            var l = $(u, o);
                            if ("invoke" !== u[1]) l && e.isDefined(c) && c[u[1]].apply(c, u[2]);
                            else {
                                var d = function(n) {
                                    var r = t.indexOf(o + "-" + n);
                                    (-1 === r || i) && (-1 === r && t.push(o + "-" + n), e.isDefined(c) && c[u[1]].apply(c, u[2]))
                                };
                                if (e.isFunction(u[2][0])) d(u[2][0]);
                                else if (e.isArray(u[2][0]))
                                    for (var f = 0, h = u[2][0].length; h > f; f++) e.isFunction(u[2][0][f]) && d(u[2][0][f])
                            }
                        }
                }
            }
    
            function E(n) {
                var r = null;
                return e.isString(n) ? r = n : e.isObject(n) && n.hasOwnProperty("name") && e.isString(n.name) && (r = n.name), r
            }
    
            function _(n) {
                if (!e.isString(n)) return !1;
                try {
                    return g(n)
                } catch (r) {
                    if (/No module/.test(r) || r.message.indexOf("$injector:nomod") > -1) return !1
                }
            }
            var w = {},
                O = {
                    $controllerProvider: d,
                    $compileProvider: p,
                    $filterProvider: m,
                    $provide: f,
                    $injector: v,
                    $animateProvider: y
                },
                x = !1,
                b = !1,
                z = [],
                D = {};
            z.push = function(e) {
                -1 === this.indexOf(e) && Array.prototype.push.apply(this, arguments)
            }, this.config = function(n) {
                e.isDefined(n.modules) && (e.isArray(n.modules) ? e.forEach(n.modules, function(e) {
                    w[e.name] = e
                }) : w[n.modules.name] = n.modules), e.isDefined(n.debug) && (x = n.debug), e.isDefined(n.events) && (b = n.events)
            }, this._init = function(o) {
                if (0 === i.length) {
                    var t = [o],
                        a = ["ng:app", "ng-app", "x-ng-app", "data-ng-app"],
                        u = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/,
                        c = function(e) {
                            return e && t.push(e)
                        };
                    e.forEach(a, function(n) {
                        a[n] = !0, c(document.getElementById(n)), n = n.replace(":", "\\:"), "undefined" != typeof o[0] && o[0].querySelectorAll && (e.forEach(o[0].querySelectorAll("." + n), c), e.forEach(o[0].querySelectorAll("." + n + "\\:"), c), e.forEach(o[0].querySelectorAll("[" + n + "]"), c))
                    }), e.forEach(t, function(n) {
                        if (0 === i.length) {
                            var r = " " + o.className + " ",
                                t = u.exec(r);
                            t ? i.push((t[2] || "").replace(/\s+/g, ",")) : e.forEach(n.attributes, function(e) {
                                0 === i.length && a[e.name] && i.push(e.value)
                            })
                        }
                    })
                }
                0 !== i.length || (n.jasmine || n.mocha) && e.isDefined(e.mock) || console.error("No module found during bootstrap, unable to init ocLazyLoad. You should always use the ng-app directive or angular.boostrap when you use ocLazyLoad.");
                var l = function d(n) {
                    if (-1 === r.indexOf(n)) {
                        r.push(n);
                        var o = e.module(n);
                        j(null, o._invokeQueue, n), j(null, o._configBlocks, n), e.forEach(o.requires, d)
                    }
                };
                e.forEach(i, function(e) {
                    l(e)
                }), i = [], s.pop()
            };
            var S = function(n) {
                    try {
                        return JSON.stringify(n)
                    } catch (r) {
                        var o = [];
                        return JSON.stringify(n, function(n, r) {
                            if (e.isObject(r) && null !== r) {
                                if (-1 !== o.indexOf(r)) return;
                                o.push(r)
                            }
                            return r
                        })
                    }
                },
                M = function(e) {
                    var n, r, o, t = 0;
                    if (0 == e.length) return t;
                    for (n = 0, o = e.length; o > n; n++) r = e.charCodeAt(n), t = (t << 5) - t + r, t |= 0;
                    return t
                };
            this.$get = ["$log", "$rootElement", "$rootScope", "$cacheFactory", "$q", function(n, t, a, c, d) {
                function f(e) {
                    var r = d.defer();
                    return n.error(e.message), r.reject(e), r.promise
                }
                var p, m = c("ocLazyLoad");
                return x || (n = {}, n.error = e.noop, n.warn = e.noop, n.info = e.noop), O.getInstanceInjector = function() {
                    return p ? p : p = t.data("$injector") || e.injector()
                }, u = function(e, r) {
                    b && a.$broadcast(e, r), x && n.info(e, r)
                }, {
                    _broadcast: u,
                    _$log: n,
                    _getFilesCache: function() {
                        return m
                    },
                    toggleWatch: function(e) {
                        e ? s.push(!0) : s.pop()
                    },
                    getModuleConfig: function(n) {
                        if (!e.isString(n)) throw new Error("You need to give the name of the module to get");
                        return w[n] ? e.copy(w[n]) : null
                    },
                    setModuleConfig: function(n) {
                        if (!e.isObject(n)) throw new Error("You need to give the module config object to set");
                        return w[n.name] = n, n
                    },
                    getModules: function() {
                        return r
                    },
                    isLoaded: function(n) {
                        var o = function(e) {
                            var n = r.indexOf(e) > -1;
                            return n || (n = !!_(e)), n
                        };
                        if (e.isString(n) && (n = [n]), e.isArray(n)) {
                            var t, i;
                            for (t = 0, i = n.length; i > t; t++)
                                if (!o(n[t])) return !1;
                            return !0
                        }
                        throw new Error("You need to define the module(s) name(s)")
                    },
                    _getModuleName: E,
                    _getModule: function(e) {
                        try {
                            return g(e)
                        } catch (n) {
                            throw (/No module/.test(n) || n.message.indexOf("$injector:nomod") > -1) && (n.message = 'The module "' + S(e) + '" that you are trying to load does not exist. ' + n.message), n
                        }
                    },
                    moduleExists: _,
                    _loadDependencies: function(n, r) {
                        var o, t, i, a = [],
                            s = this;
                        if (n = s._getModuleName(n), null === n) return d.when();
                        try {
                            o = s._getModule(n)
                        } catch (u) {
                            return f(u)
                        }
                        return t = s.getRequires(o), e.forEach(t, function(o) {
                            if (e.isString(o)) {
                                var t = s.getModuleConfig(o);
                                if (null === t) return void z.push(o);
                                o = t, t.name = void 0
                            }
                            if (s.moduleExists(o.name)) return i = o.files.filter(function(e) {
                                return s.getModuleConfig(o.name).files.indexOf(e) < 0
                            }), 0 !== i.length && s._$log.warn('Module "', n, '" attempted to redefine configuration for dependency. "', o.name, '"\n Additional Files Loaded:', i), e.isDefined(s.filesLoader) ? void a.push(s.filesLoader(o, r).then(function() {
                                return s._loadDependencies(o)
                            })) : f(new Error("Error: New dependencies need to be loaded from external files (" + o.files + "), but no loader has been defined."));
                            if (e.isArray(o)) {
                                var u = [];
                                e.forEach(o, function(e) {
                                    var n = s.getModuleConfig(e);
                                    null === n ? u.push(e) : n.files && (u = u.concat(n.files))
                                }), u.length > 0 && (o = {
                                    files: u
                                })
                            } else e.isObject(o) && o.hasOwnProperty("name") && o.name && (s.setModuleConfig(o), z.push(o.name));
                            if (e.isDefined(o.files) && 0 !== o.files.length) {
                                if (!e.isDefined(s.filesLoader)) return f(new Error('Error: the module "' + o.name + '" is defined in external files (' + o.files + "), but no loader has been defined."));
                                a.push(s.filesLoader(o, r).then(function() {
                                    return s._loadDependencies(o)
                                }))
                            }
                        }), d.all(a)
                    },
                    inject: function(n) {
                        var r = arguments.length <= 1 || void 0 === arguments[1] ? {} : arguments[1],
                            o = arguments.length <= 2 || void 0 === arguments[2] ? !1 : arguments[2],
                            t = this,
                            a = d.defer();
                        if (e.isDefined(n) && null !== n) {
                            if (e.isArray(n)) {
                                var s = [];
                                return e.forEach(n, function(e) {
                                    s.push(t.inject(e, r, o))
                                }), d.all(s)
                            }
                            t._addToLoadList(t._getModuleName(n), !0, o)
                        }
                        if (i.length > 0) {
                            var u = i.slice(),
                                c = function f(e) {
                                    z.push(e), D[e] = a.promise, t._loadDependencies(e, r).then(function() {
                                        try {
                                            l = [], L(O, z, r)
                                        } catch (e) {
                                            return t._$log.error(e.message), void a.reject(e)
                                        }
                                        i.length > 0 ? f(i.shift()) : a.resolve(u)
                                    }, function(e) {
                                        a.reject(e)
                                    })
                                };
                            c(i.shift())
                        } else {
                            if (r && r.name && D[r.name]) return D[r.name];
                            a.resolve()
                        }
                        return a.promise
                    },
                    getRequires: function(n) {
                        var o = [];
                        return e.forEach(n.requires, function(e) {
                            -1 === r.indexOf(e) && o.push(e)
                        }), o
                    },
                    _invokeQueue: j,
                    _registerInvokeList: $,
                    _register: L,
                    _addToLoadList: h,
                    _unregister: function(n) {
                        e.isDefined(n) && e.isArray(n) && e.forEach(n, function(e) {
                            o[e] = void 0
                        })
                    }
                }
            }], this._init(e.element(n.document))
        }]);
        var f = e.bootstrap;
        e.bootstrap = function(n, r, o) {
            return e.forEach(r.slice(), function(e) {
                h(e, !0, !0)
            }), f(n, r, o)
        };
        var h = function(n, r, o) {
                (s.length > 0 || r) && e.isString(n) && -1 === i.indexOf(n) && (i.push(n), o && a.push(n))
            },
            g = e.module;
        e.module = function(e, n, r) {
            return h(e, !1, !0), g(e, n, r)
        }, "undefined" != typeof module && "undefined" != typeof exports && module.exports === exports && (module.exports = "oc.lazyLoad")
    }(angular, window),
    function(e) {
        "use strict";
        e.module("oc.lazyLoad").directive("ocLazyLoad", ["$ocLazyLoad", "$compile", "$animate", "$parse", "$timeout", function(n, r, o, t, i) {
            return {
                restrict: "A",
                terminal: !0,
                priority: 1e3,
                compile: function(i, a) {
                    var s = i[0].innerHTML;
                    return i.html(""),
                        function(i, a, u) {
                            var c = t(u.ocLazyLoad);
                            i.$watch(function() {
                                return c(i) || u.ocLazyLoad
                            }, function(t) {
                                e.isDefined(t) && n.load(t).then(function() {
                                    o.enter(s, a), r(a.contents())(i)
                                })
                            }, !0)
                        }
                }
            }
        }])
    }(angular),
    function(e) {
        "use strict";
        e.module("oc.lazyLoad").config(["$provide", function(n) {
            n.decorator("$ocLazyLoad", ["$delegate", "$q", "$window", "$interval", function(n, r, o, t) {
                var i = !1,
                    a = !1,
                    s = o.document.getElementsByTagName("head")[0] || o.document.getElementsByTagName("body")[0];
                return n.buildElement = function(u, c, l) {
                    var d, f, h = r.defer(),
                        g = n._getFilesCache(),
                        p = function(e) {
                            var n = (new Date).getTime();
                            return e.indexOf("?") >= 0 ? "&" === e.substring(0, e.length - 1) ? e + "_dc=" + n : e + "&_dc=" + n : e + "?_dc=" + n
                        };
                    switch (e.isUndefined(g.get(c)) && g.put(c, h.promise), u) {
                        case "css":
                            d = o.document.createElement("link"), d.type = "text/css", d.rel = "stylesheet", d.href = l.cache === !1 ? p(c) : c;
                            break;
                        case "js":
                            d = o.document.createElement("script"), d.src = l.cache === !1 ? p(c) : c;
                            break;
                        default:
                            g.remove(c), h.reject(new Error('Requested type "' + u + '" is not known. Could not inject "' + c + '"'))
                    }
                    d.onload = d.onreadystatechange = function(e) {
                        d.readyState && !/^c|loade/.test(d.readyState) || f || (d.onload = d.onreadystatechange = null, f = 1, n._broadcast("ocLazyLoad.fileLoaded", c), h.resolve())
                    }, d.onerror = function() {
                        g.remove(c), h.reject(new Error("Unable to load " + c))
                    }, d.async = l.serie ? 0 : 1;
                    var m = s.lastChild;
                    if (l.insertBefore) {
                        var v = e.element(e.isDefined(window.jQuery) ? l.insertBefore : document.querySelector(l.insertBefore));
                        v && v.length > 0 && (m = v[0])
                    }
                    if (m.parentNode.insertBefore(d, m), "css" == u) {
                        if (!i) {
                            var y = o.navigator.userAgent.toLowerCase();
                            if (/iP(hone|od|ad)/.test(o.navigator.platform)) {
                                var L = o.navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/),
                                    $ = parseFloat([parseInt(L[1], 10), parseInt(L[2], 10), parseInt(L[3] || 0, 10)].join("."));
                                a = 6 > $
                            } else if (y.indexOf("android") > -1) {
                                var j = parseFloat(y.slice(y.indexOf("android") + 8));
                                a = 4.4 > j
                            } else if (y.indexOf("safari") > -1) {
                                var E = y.match(/version\/([\.\d]+)/i);
                                a = E && E[1] && parseFloat(E[1]) < 6
                            }
                        }
                        if (a) var _ = 1e3,
                            w = t(function() {
                                try {
                                    d.sheet.cssRules, t.cancel(w), d.onload()
                                } catch (e) {
                                    --_ <= 0 && d.onerror()
                                }
                            }, 20)
                    }
                    return h.promise
                }, n
            }])
        }])
    }(angular),
    function(e) {
        "use strict";
        e.module("oc.lazyLoad").config(["$provide", function(n) {
            n.decorator("$ocLazyLoad", ["$delegate", "$q", function(n, r) {
                return n.filesLoader = function(o) {
                    var t = arguments.length <= 1 || void 0 === arguments[1] ? {} : arguments[1],
                        i = [],
                        a = [],
                        s = [],
                        u = [],
                        c = null,
                        l = n._getFilesCache();
                    n.toggleWatch(!0), e.extend(t, o);
                    var d = function(r) {
                        var o, d = null;
                        if (e.isObject(r) && (d = r.type, r = r.path), c = l.get(r), e.isUndefined(c) || t.cache === !1) {
                            if (null !== (o = /^(css|less|html|htm|js)?(?=!)/.exec(r)) && (d = o[1], r = r.substr(o[1].length + 1, r.length)), !d)
                                if (null !== (o = /[.](css|less|html|htm|js)?((\?|#).*)?$/.exec(r))) d = o[1];
                                else {
                                    if (n.jsLoader.hasOwnProperty("ocLazyLoadLoader") || !n.jsLoader.hasOwnProperty("requirejs")) return void n._$log.error("File type could not be determined. " + r);
                                    d = "js"
                                }
                            "css" !== d && "less" !== d || -1 !== i.indexOf(r) ? "html" !== d && "htm" !== d || -1 !== a.indexOf(r) ? "js" === d || -1 === s.indexOf(r) ? s.push(r) : n._$log.error("File type is not valid. " + r) : a.push(r) : i.push(r)
                        } else c && u.push(c)
                    };
                    if (t.serie ? d(t.files.shift()) : e.forEach(t.files, function(e) {
                            d(e)
                        }), i.length > 0) {
                        var f = r.defer();
                        n.cssLoader(i, function(r) {
                            e.isDefined(r) && n.cssLoader.hasOwnProperty("ocLazyLoadLoader") ? (n._$log.error(r), f.reject(r)) : f.resolve()
                        }, t), u.push(f.promise)
                    }
                    if (a.length > 0) {
                        var h = r.defer();
                        n.templatesLoader(a, function(r) {
                            e.isDefined(r) && n.templatesLoader.hasOwnProperty("ocLazyLoadLoader") ? (n._$log.error(r), h.reject(r)) : h.resolve()
                        }, t), u.push(h.promise)
                    }
                    if (s.length > 0) {
                        var g = r.defer();
                        n.jsLoader(s, function(r) {
                            e.isDefined(r) && (n.jsLoader.hasOwnProperty("ocLazyLoadLoader") || n.jsLoader.hasOwnProperty("requirejs")) ? (n._$log.error(r), g.reject(r)) : g.resolve()
                        }, t), u.push(g.promise)
                    }
                    if (0 === u.length) {
                        var p = r.defer(),
                            m = "Error: no file to load has been found, if you're trying to load an existing module you should use the 'inject' method instead of 'load'.";
                        return n._$log.error(m), p.reject(m), p.promise
                    }
                    return t.serie && t.files.length > 0 ? r.all(u).then(function() {
                        return n.filesLoader(o, t)
                    }) : r.all(u)["finally"](function(e) {
                        return n.toggleWatch(!1), e
                    })
                }, n.load = function(o) {
                    var t, i = arguments.length <= 1 || void 0 === arguments[1] ? {} : arguments[1],
                        a = this,
                        s = null,
                        u = [],
                        c = r.defer(),
                        l = e.copy(o),
                        d = e.copy(i);
                    if (e.isArray(l)) return e.forEach(l, function(e) {
                        u.push(a.load(e, d))
                    }), r.all(u).then(function(e) {
                        c.resolve(e)
                    }, function(e) {
                        c.reject(e)
                    }), c.promise;
                    if (e.isString(l) ? (s = a.getModuleConfig(l), s || (s = {
                            files: [l]
                        })) : e.isObject(l) && (s = e.isDefined(l.path) && e.isDefined(l.type) ? {
                            files: [l]
                        } : a.setModuleConfig(l)), null === s) {
                        var f = a._getModuleName(l);
                        return t = 'Module "' + (f || "unknown") + '" is not configured, cannot load.', n._$log.error(t), c.reject(new Error(t)), c.promise
                    }
                    e.isDefined(s.template) && (e.isUndefined(s.files) && (s.files = []), e.isString(s.template) ? s.files.push(s.template) : e.isArray(s.template) && s.files.concat(s.template));
                    var h = e.extend({}, d, s);
                    return e.isUndefined(s.files) && e.isDefined(s.name) && n.moduleExists(s.name) ? n.inject(s.name, h, !0) : (n.filesLoader(s, h).then(function() {
                        n.inject(null, h).then(function(e) {
                            c.resolve(e)
                        }, function(e) {
                            c.reject(e)
                        })
                    }, function(e) {
                        c.reject(e)
                    }), c.promise)
                }, n
            }])
        }])
    }(angular),
    function(e) {
        "use strict";
        e.module("oc.lazyLoad").config(["$provide", function(n) {
            n.decorator("$ocLazyLoad", ["$delegate", "$q", function(n, r) {
                return n.cssLoader = function(o, t, i) {
                    var a = [];
                    e.forEach(o, function(e) {
                        a.push(n.buildElement("css", e, i))
                    }), r.all(a).then(function() {
                        t()
                    }, function(e) {
                        t(e)
                    })
                }, n.cssLoader.ocLazyLoadLoader = !0, n
            }])
        }])
    }(angular),
    function(e) {
        "use strict";
        e.module("oc.lazyLoad").config(["$provide", function(n) {
            n.decorator("$ocLazyLoad", ["$delegate", "$q", function(n, r) {
                return n.jsLoader = function(o, t, i) {
                    var a = [];
                    e.forEach(o, function(e) {
                        a.push(n.buildElement("js", e, i))
                    }), r.all(a).then(function() {
                        t()
                    }, function(e) {
                        t(e)
                    })
                }, n.jsLoader.ocLazyLoadLoader = !0, n
            }])
        }])
    }(angular),
    function(e) {
        "use strict";
        e.module("oc.lazyLoad").config(["$provide", function(n) {
            n.decorator("$ocLazyLoad", ["$delegate", "$templateCache", "$q", "$http", function(n, r, o, t) {
                return n.templatesLoader = function(i, a, s) {
                    var u = [],
                        c = n._getFilesCache();
                    return e.forEach(i, function(n) {
                        var i = o.defer();
                        u.push(i.promise), t.get(n, s).success(function(o) {
                            e.isString(o) && o.length > 0 && e.forEach(e.element(o), function(e) {
                                "SCRIPT" === e.nodeName && "text/ng-template" === e.type && r.put(e.id, e.innerHTML)
                            }), e.isUndefined(c.get(n)) && c.put(n, !0), i.resolve()
                        }).error(function(e) {
                            i.reject(new Error('Unable to load template file "' + n + '": ' + e))
                        })
                    }), o.all(u).then(function() {
                        a()
                    }, function(e) {
                        a(e)
                    })
                }, n.templatesLoader.ocLazyLoadLoader = !0, n
            }])
        }])
    }(angular), Array.prototype.indexOf || (Array.prototype.indexOf = function(e, n) {
        var r;
        if (null == this) throw new TypeError('"this" is null or not defined');
        var o = Object(this),
            t = o.length >>> 0;
        if (0 === t) return -1;
        var i = +n || 0;
        if (Math.abs(i) === 1 / 0 && (i = 0), i >= t) return -1;
        for (r = Math.max(i >= 0 ? i : t - Math.abs(i), 0); t > r;) {
            if (r in o && o[r] === e) return r;
            r++
        }
        return -1
    });
    /*! RESOURCE: /scripts/snm/cabrillo/js_includes_cabrillo.js */
    /*! RESOURCE: /scripts/snm/cabrillo/core.js */
    (function(window, undefined) {
        'use strict';
        var cabrillo = {
            isNative: isNative,
            postMethod: postMethod,
            callMethod: callMethod,
            receiveMethod: receiveMethod,
            EXPORT_NAME: 'snmCabrillo',
            CLIENT_EXPORT_NAME: 'CabrilloClient',
            PACKAGE: 'com.servicenow.cabrillo',
            DEBUG: true,
            extend: extend,
            copyValues: copyValues,
            log: log,
            q: QInterface()
        };
        window[cabrillo.EXPORT_NAME] = cabrillo;
        var CabrilloClient = window[cabrillo.CLIENT_EXPORT_NAME];
        var cabrilloClientConfig = {
            isNative: true,
            acceptObjects: false,
            supportedMethods: null
        };
        if (typeof CabrilloClient === 'undefined') {
            CabrilloClient = _getIOSClient();
            if (!CabrilloClient) {
                CabrilloClient = _getWebClient();
            }
        }
        (function() {
            var clientConfig = CabrilloClient.getConfig();
            if (!clientConfig) {
                return;
            }
            if (typeof clientConfig === 'string') {
                clientConfig = JSON.parse(clientConfig);
            }
            extend(cabrilloClientConfig, clientConfig);
        })();
        var _methods = null;
        if (cabrilloClientConfig.supportedMethods) {
            _methods = {};
            cabrilloClientConfig.supportedMethods.forEach(function(name) {
                _methods[name] = true;
            });
        }
    
        function _getIOSClient() {
            var webkit = window.webkit;
            var _nativeMethod = webkit && webkit.messageHandlers ? webkit.messageHandlers[cabrillo.PACKAGE + '.camera.getBarcode'] : undefined;
            if (typeof _nativeMethod === 'undefined') {
                return;
            }
            var _client = {
                getConfig: function() {
                    return {
                        acceptObjects: true,
                        supportedMethods: null
                    };
                },
                hasMethod: function(name) {
                    var method = webkit ? webkit.messageHandlers[name] : undefined;
                    return (typeof method !== 'undefined');
                },
                postMethod: function(name, data) {
                    if (!_client.hasMethod(name)) {
                        log('Missing method: ' + name);
                        return;
                    }
                    var method = webkit.messageHandlers[name];
                    method.postMessage(data);
                }
            };
            return _client;
        }
    
        function _getWebClient() {
            return {
                getConfig: function() {
                    return {
                        isNative: false,
                        acceptObjects: true,
                        supportedMethods: []
                    };
                },
                hasMethod: function() {
                    return false;
                },
                postMethod: function() {}
            };
        }
    
        function isNative() {
            return cabrilloClientConfig.isNative;
        }
    
        function _hasMethod(name) {
            if (_methods) {
                return _methods[name];
            }
            if (CabrilloClient.hasMethod) {
                return CabrilloClient.hasMethod(name);
            }
            return false;
        }
    
        function extend(defaults, options, newObject) {
            var extended = newObject ? {} : defaults;
            var prop;
            for (prop in defaults) {
                if (Object.prototype.hasOwnProperty.call(defaults, prop)) {
                    extended[prop] = defaults[prop];
                }
            }
            for (prop in options) {
                if (Object.prototype.hasOwnProperty.call(options, prop)) {
                    extended[prop] = options[prop];
                }
            }
            return extended;
        }
    
        function copyValues(dest, source) {
            for (var prop in source) {
                if (Object.prototype.hasOwnProperty.call(source, prop)) {
                    switch (typeof source[prop]) {
                        case 'function':
                            break;
                        default:
                            dest[prop] = source[prop];
                    }
                }
            }
            return dest;
        }
    
        function log(msg) {
            if (!cabrillo.DEBUG) {
                return;
            }
            var args = Array.prototype.slice.call(arguments, 0);
            args.unshift('(Cabrillo)');
            console.log.apply(console, args);
        }
    
        function postMethod(name, data) {
            if (!cabrilloClientConfig.acceptObjects) {
                data = JSON.stringify(data);
            }
            CabrilloClient.postMethod(name, data);
        }
        var _callId = 0;
        var _openCalls = {};
    
        function callMethod(name, data, context) {
            var defer = _getDeferred();
            if (!_hasMethod(name)) {
                var err = 'Missing method: ' + name;
                defer.reject(err);
                return defer.promise;
            }
            var callId = _callId++;
            var callbackContext = extend(context, {
                callId: callId
            }, true);
            var requestPayload = {
                callbackName: cabrillo.EXPORT_NAME + '.receiveMethod',
                callbackContext: callbackContext,
                options: data
            };
            _openCalls[callId] = {
                defer: defer
            };
            postMethod(name, requestPayload);
            return defer.promise;
        }
    
        function receiveMethod(data) {
            if (!cabrilloClientConfig.acceptObjects) {
                data = JSON.parse(data);
            }
            var context = data.callbackContext;
            var openCall = _openCalls[context.callId];
            if (!openCall) {
                log('No open call found for request', data);
                return
            }
            delete context.callId;
            openCall.defer.resolve(data);
            delete _openCalls[context.callId];
        }
    
        function _getDeferred() {
            return cabrillo.q.defer();
        }
    
        function QInterface() {
            return {
                defer: function() {
                    return new QDeferred();
                },
                reject: function() {
                    return false;
                }
            };
        };
    
        function QDeferred() {
            var dones = [];
            var fails = [];
            var state = null;
            var payload = null;
            this.promise = {
                then: function(done, fail) {
                    dones.push(done);
                    fails.push(fail);
                    notify();
                    return this;
                }
            };
            this.resolve = function(data) {
                if (state) {
                    return;
                }
                state = 'done';
                payload = data;
                notify();
            };
            this.reject = function(reason) {
                if (state) {
                    return;
                }
                state = 'fail';
                payload = reason;
                notify();
            };
    
            function notify() {
                switch (state) {
                    case 'done':
                        dones.forEach(function(done) {
                            if (done) {
                                payload = done.call(done, payload);
                            }
                        });
                        dones = [];
                        fails = [];
                        break;
                    case 'fail':
                        fails.forEach(function(fail) {
                            if (fail) {
                                payload = fail.call(fail, payload);
                            }
                        });
                        dones = [];
                        fails = [];
                        break;
                    default:
                }
            }
        }
    })(window);;
    /*! RESOURCE: /scripts/snm/cabrillo/attachments.js */
    (function(window, cabrillo, undefined) {
        'use strict';
        var PACKAGE = 'attachments';
        cabrillo.extend(cabrillo, {
            attachments: {
                addFile: addFile,
                viewFile: viewFile
            }
        });
        var ADD_ATTACHMENTS_URL = '/angular.do?sysparm_type=ngk_attachments&action=add&load_attachment_record=true';
    
        function addFile(tableName, sysID, params, options) {
            var uploadParams = cabrillo.extend({
                attachments_modified: 'true',
                sysparm_table: tableName,
                sysparm_sys_id: sysID,
                sysparm_nostack: 'yes',
                sysparm_encryption_context: ''
            }, params || {});
            var apiPath = ADD_ATTACHMENTS_URL + '&sys_id=' + sysID + '&table=' + tableName;
            options = options || {};
            return callMethod('addFile', {
                apiPath: apiPath,
                params: uploadParams,
                uploadParamName: 'attachFile',
                sourceRect: options.sourceRect,
                maxWidth: options.maxWidth,
                maxHeight: options.maxHeight,
                jpgQuality: options.jpgQuality
            }).then(function(response) {
                return response.results;
            });
        }
    
        function viewFile(attachment, sourceRect, sourceBase64) {
            return callMethod('viewFile', {
                attachment: {
                    sys_id: attachment.sys_id,
                    content_type: attachment.content_type,
                    file_name: attachment.file_name,
                    sys_updated_on: attachment.sys_updated_on,
                    path: attachment.sys_id + '.iix',
                    thumbnail_path: attachment.thumbSrc
                },
                sourceRect: sourceRect,
                sourceBase64: sourceBase64
            });
        }
    
        function callMethod(methodName, data) {
            return cabrillo.callMethod(cabrillo.PACKAGE + '.' + PACKAGE + '.' + methodName, data);
        }
    })(window, window['snmCabrillo']);;
    /*! RESOURCE: /scripts/snm/cabrillo/camera.js */
    (function(window, cabrillo, undefined) {
        'use strict';
        var PACKAGE = 'camera';
        cabrillo.extend(cabrillo, {
            camera: {
                getBarcode: getBarcode
            }
        });
    
        function getBarcode() {
            return callMethod('getBarcode').then(function(data) {
                return data.results;
            }, function(err) {
                cabrillo.log('Failed to get barcode value:', err);
                return cabrillo.q.reject(err);
            });
        }
    
        function callMethod(methodName, data) {
            return cabrillo.callMethod(cabrillo.PACKAGE + '.' + PACKAGE + '.' + methodName, data);
        }
    })(window, window['snmCabrillo']);;
    /*! RESOURCE: /scripts/snm/cabrillo/debug.js */
    (function(window, cabrillo, undefined) {
        'use strict';
        var PACKAGE = 'debug';
        cabrillo.extend(cabrillo, {
            debug: {
                log: log
            }
        });
    
        function log(message) {
            cabrillo.log(message);
            callMethod('log', {
                message: message
            });
        }
    
        function callMethod(methodName, data) {
            return cabrillo.callMethod(cabrillo.PACKAGE + '.' + PACKAGE + '.' + methodName, data);
        }
    })(window, window['snmCabrillo']);;
    /*! RESOURCE: /scripts/snm/cabrillo/form.js */
    (function(window, cabrillo, undefined) {
        'use strict';
        var PACKAGE = 'form';
        cabrillo.extend(cabrillo, {
            form: {
                didChangeRecord: didChangeRecord
            }
        });
    
        function didChangeRecord(isNewRecord, tableName, sysId) {
            if (isNewRecord) {
                didCreateRecord(tableName, sysId);
            } else {
                didUpdateRecord(tableName, sysId);
            }
        }
    
        function didCreateRecord(tableName, sysId) {
            callMethod('didCreateRecord', {
                table: tableName,
                sysId: sysId
            });
        }
    
        function didUpdateRecord(tableName, sysId) {
            callMethod('didUpdateRecord', {
                table: tableName,
                sysId: sysId
            });
        }
    
        function callMethod(methodName, data) {
            return cabrillo.callMethod(cabrillo.PACKAGE + '.' + PACKAGE + '.' + methodName, data);
        }
    })(window, window['snmCabrillo']);;
    /*! RESOURCE: /scripts/snm/cabrillo/geolocation.js */
    (function(window, cabrillo, undefined) {
        'use strict';
        var PACKAGE = 'geolocation';
        cabrillo.extend(cabrillo, {
            geolocation: {
                getCurrentLocation: getCurrentLocation
            }
        });
    
        function getCurrentLocation() {
            return callMethod('getCurrentLocation').then(function(data) {
                return data.results;
            }, function(err) {
                cabrillo.log('Failed to get geolocation value:', err);
                return cabrillo.q.reject(err);
            });
        }
    
        function callMethod(methodName, data) {
            return cabrillo.callMethod(cabrillo.PACKAGE + '.' + PACKAGE + '.' + methodName, data);
        }
    })(window, window['snmCabrillo']);;
    /*! RESOURCE: /scripts/snm/cabrillo/list.js */
    (function(window, cabrillo, undefined) {
        'use strict';
        var PACKAGE = 'list';
        cabrillo.extend(cabrillo, {
            list: {
                selectItem: selectItem,
                selectItems: selectItems
            }
        });
    
        function selectItem(title, tableName, query, selectedItem, params) {
            var _selectedItem;
            if (selectedItem) {
                _selectedItem = {
                    value: selectedItem.value,
                    displayValue: selectedItem.displayValue
                };
            }
            return callMethod('selectItem', {
                title: title,
                table: tableName,
                query: query,
                selectedItem: _selectedItem,
                params: params
            }).then(function(data) {
                cabrillo.log('selectItem response', arguments);
                return data.results;
            });
        }
    
        function selectItems(title, tableName, query, selectedItems, params) {
            return callMethod('selectItems', {
                title: title,
                table: tableName,
                query: query,
                selectedItems: selectedItems,
                params: params
            }).then(function(data) {
                cabrillo.log('selectItems response', arguments);
                return data.results;
            });
        }
    
        function callMethod(methodName, data) {
            return cabrillo.callMethod(cabrillo.PACKAGE + '.' + PACKAGE + '.' + methodName, data);
        }
    })(window, window['snmCabrillo']);;
    /*! RESOURCE: /scripts/snm/cabrillo/modal.js */
    (function(window, cabrillo, undefined) {
        'use strict';
        var PACKAGE = 'modal';
        cabrillo.extend(cabrillo, {
            modal: {
                MODAL_PRESENTATION_STYLE_FULL_SCREEN: 'fullScreen',
                MODAL_PRESENTATION_STYLE_FORM_SHEET: 'formSheet',
                CLOSE_BUTTON_STYLE_CANCEL: 'cancel',
                CLOSE_BUTTON_STYLE_CLOSE: 'close',
                presentModal: presentModal,
                dismissModal: dismissModal
            }
        });
    
        function presentModal(title, url, closeButtonStyle, modalPresentationStyle) {
            return callMethod('presentModal', {
                title: title,
                url: url,
                closeButtonStyle: closeButtonStyle ? closeButtonStyle : null,
                modalPresentationStyle: modalPresentationStyle ? modalPresentationStyle : null
            }).then(function(data) {
                return data.results;
            }, function(err) {
                cabrillo.log('presentModal error: ' + err);
            });
        }
    
        function dismissModal(data, redirect) {
            return callMethod('dismissModal', {
                results: {
                    results: data,
                    redirect: redirect
                }
            });
        }
    
        function callMethod(methodName, data, context) {
            return cabrillo.callMethod(cabrillo.PACKAGE + '.' + PACKAGE + '.' + methodName, data, context);
        }
    })(window, window['snmCabrillo']);;
    /*! RESOURCE: /scripts/snm/cabrillo/navigation.js */
    (function(window, cabrillo, undefined) {
        'use strict';
        var PACKAGE = 'navigation';
        cabrillo.extend(cabrillo, {
            navigation: {
                goto: goto,
                goBack: goBack
            }
        });
    
        function goto(uri, params) {
            params = params || {};
            return callMethod('goto', {
                uri: uri,
                table: params.table,
                sysId: params.sysId,
                query: params.query
            });
        }
    
        function goBack() {
            callMethod('goBack');
        }
    
        function callMethod(methodName, data) {
            return cabrillo.callMethod(cabrillo.PACKAGE + '.' + PACKAGE + '.' + methodName, data);
        }
    })(window, window['snmCabrillo']);;
    /*! RESOURCE: /scripts/snm/cabrillo/viewLayout.js */
    (function(window, cabrillo, undefined) {
        'use strict';
        var PACKAGE = 'viewLayout';
        cabrillo.extend(cabrillo, {
            'viewLayout': {
                MORE_MENU_BUTTON_STYLE: 'moreMenuButtonStyle',
                SUCCESS_SPINNER_STYLE: 'successStyle',
                setTitle: setTitle,
                setNavigationBarButtons: setNavigationBarButtons,
                setBottomButtons: setBottomButtons,
                showSpinner: showSpinner,
                hideSpinner: hideSpinner,
                executeCallback: executeCallback
            }
        });
        var _callbackHandlers = {};
        var _callbackHandlerId = 0;
    
        function setTitle(title) {
            return callMethod('setTitle', {
                title: title
            });
        }
    
        function setNavigationBarButtons(buttons, execute) {
            var externalHandler = _registerCallbackHandler('registerNavigationBarButtons', buttons, execute);
            return callMethod('setNavigationBarButtons', {
                buttons: externalHandler.payloads
            }).then(function() {
                return externalHandler;
            }, function() {
                externalHandler();
            });
        }
    
        function setBottomButtons(buttons, execute) {
            var externalHandler = _registerCallbackHandler('registerBottomButtons', buttons, execute);
            return callMethod('setBottomButtons', {
                buttons: externalHandler.payloads
            }).then(function() {
                return externalHandler;
            }, function() {
                externalHandler();
            });
        }
    
        function showSpinner(options) {
            options = options || {};
            var mask = options.mask;
            var maskColor = options.maskColor;
            callMethod('showSpinner', {
                mask: !!mask,
                maskColor: maskColor
            });
        }
    
        function hideSpinner(spinnerStyle) {
            callMethod('hideSpinner', {
                dismissStyle: spinnerStyle
            });
        }
    
        function executeCallback(handlerPayload) {
            var callbackContext = handlerPayload.callbackContext;
            var handler = _callbackHandlers[callbackContext.className];
            if (!handler || (handler.id !== callbackContext.id)) {
                cabrillo.log('Handler not found');
                return;
            }
            var activeElement = document.activeElement;
            if (activeElement) {
                activeElement.blur();
            }
            handler.executeCallback(callbackContext.payloadId);
        }
    
        function _registerCallbackHandler(handlerClass, payloads, executeCallback) {
            if (!handlerClass) {
                throw 'Handler class must be specified';
            }
            if (!payloads) {
                payloads = [];
            }
            _unregisterCallbackHandler(handlerClass);
            var handlerPayloads = [];
            var handlerId = _callbackHandlerId++;
            payloads.forEach(function(payload, payloadIndex) {
                var callbackName = cabrillo.EXPORT_NAME + '.' + PACKAGE + '.executeCallback';
                var handlerPayload = {
                    callbackName: callbackName,
                    callbackContext: {
                        id: handlerId,
                        className: handlerClass,
                        payloadId: payloadIndex
                    }
                };
                handlerPayload = cabrillo.copyValues(handlerPayload, payload);
                handlerPayload.callbackScript = callbackName + '(' + JSON.stringify(handlerPayload) + ')';
                handlerPayloads.push(handlerPayload);
            });
            var handler = function() {
                var handler = _callbackHandlers[handlerClass];
                if (handler && handler === this) {
                    handler.payloads = null;
                    handler.executeCallback = null;
                    delete _callbackHandlers[handlerClass];
                }
            };
            handler.id = handlerId;
            handler.className = handlerClass;
            handler.payloads = handlerPayloads;
            handler.executeCallback = function() {
                var handlerPayload = arguments;
                var d = cabrillo.q.defer();
                d.promise.then(function() {
                    executeCallback.apply(this, handlerPayload);
                });
                d.resolve();
            };
            _callbackHandlers[handlerClass] = handler;
            return handler;
        }
    
        function _unregisterCallbackHandler(handler) {
            var className = typeof handler === 'string' ? handler : handler.className;
            if (_callbackHandlers[className]) {
                _callbackHandlers[className]();
            }
        }
    
        function callMethod(methodName, data) {
            return cabrillo.callMethod(cabrillo.PACKAGE + '.' + PACKAGE + '.' + methodName, data);
        }
    })(window, window['snmCabrillo']);;
    /*! RESOURCE: /scripts/snm/cabrillo/angular/cabrillo.factory.js */
    if (typeof angular !== 'undefined') {
        'use strict';
        angular.module('snm.cabrillo', []).factory('cabrillo', function($window, $q) {
            var cabrillo = $window['snmCabrillo'];
            cabrillo.q = $q;
            return cabrillo;
        });
    };;
    /*! RESOURCE: /scripts/sn/common/glide/js_includes_glide.js */
    /*! RESOURCE: /scripts/sn/common/glide/_module.js */
    angular.module('sn.common.glide', [
        'sn.common.util'
    ]);;
    /*! RESOURCE: /scripts/sn/common/glide/factory.glideUrlBuilder.js */
    angular.module('sn.common.glide').factory('glideUrlBuilder', ['$window', function($window) {
        "use strict";
    
        function GlideUrl(contextPath) {
            var objDef = {
                contextPath: '',
                params: {},
                encodedString: '',
                encode: true,
                setFromCurrent: function() {
                    this.setFromString($window.location.href);
                },
                setFromString: function(href) {
                    var pos = href.indexOf('?');
                    if (pos < 0) {
                        this.contextPath = href;
                        return;
                    }
                    this.contextPath = href.slice(0, pos);
                    var hashes = href.slice(pos + 1).split('&');
                    var i = hashes.length;
                    while (i--) {
                        var pos = hashes[i].indexOf('=');
                        this.params[hashes[i].substring(0, pos)] = hashes[i].substring(++pos);
                    }
                },
                setContextPath: function(c) {
                    this.contextPath = c;
                },
                getParam: function(p) {
                    return this.params[p];
                },
                getParams: function() {
                    return this.params;
                },
                addParam: function(name, value) {
                    this.params[name] = value;
                    return this;
                },
                addToken: function() {
                    if (typeof g_ck != 'undefined' && g_ck != "")
                        this.addParam('sysparm_ck', g_ck);
                    return this;
                },
                deleteParam: function(name) {
                    delete this.params[name];
                },
                addEncodedString: function(s) {
                    if (!s)
                        return;
                    if (s.substr(0, 1) != "&")
                        this.encodedString += "&";
                    this.encodedString += s;
                    return this;
                },
                getQueryString: function(additionalParams) {
                    var qs = this._getParamsForURL(this.params);
                    qs += this._getParamsForURL(additionalParams);
                    qs += this.encodedString;
                    if (qs.length == 0)
                        return "";
                    return qs.substring(1);
                },
                _getParamsForURL: function(params) {
                    if (!params)
                        return '';
                    var url = '';
                    for (var n in params) {
                        var p = params[n] || '';
                        url += '&' + n + '=' + (this.encode ? encodeURIComponent(p + '') : p);
                    }
                    return url;
                },
                getURL: function(additionalParams) {
                    var url = this.contextPath;
                    var qs = this.getQueryString(additionalParams);
                    if (qs)
                        url += "?" + qs;
                    return url;
                },
                setEncode: function(b) {
                    this.encode = b;
                },
                toString: function() {
                    return 'GlideURL';
                }
            }
            return objDef;
        }
        return {
            newGlideUrl: function(contextPath) {
                var glideUrl = new GlideUrl();
                glideUrl.setFromString(contextPath ? contextPath : '');
                return glideUrl;
            },
            refresh: function() {
                $window.location.replace($window.location.href);
            },
            getCancelableLink: function(link) {
                if ($window.NOW && $window.NOW.g_cancelPreviousTransaction) {
                    var nextChar = link.indexOf('?') > -1 ? '&' : '?';
                    link += nextChar + "sysparm_cancelable=true";
                }
                return link;
            }
        };
    }]);;
    /*! RESOURCE: /scripts/sn/common/glide/service.queryFilter.js */
    angular.module('sn.common.glide').factory('queryFilter', function() {
        "use strict";
        return {
            create: function() {
                var that = {};
                that.conditions = [];
    
                function newCondition(field, operator, value, label, displayValue, type) {
                    var condition = {
                        field: field,
                        operator: operator,
                        value: value,
                        displayValue: displayValue,
                        label: label,
                        left: null,
                        right: null,
                        type: null,
                        setValue: function(value, displayValue) {
                            this.value = value;
                            this.displayValue = displayValue ? displayValue : value;
                        }
                    };
                    if (type)
                        condition.type = type;
                    return condition;
                }
    
                function addCondition(condition) {
                    that.conditions.push(condition);
                    return condition;
                }
    
                function removeCondition(condition) {
                    for (var i = that.conditions.length - 1; i >= 0; i--) {
                        if (that.conditions[i] === condition)
                            that.conditions.splice(i, 1);
                    }
                }
    
                function getConditionsByField(conditions, field) {
                    var conditionsToReturn = [];
                    for (var condition in conditions) {
                        if (conditions.hasOwnProperty(condition)) {
                            if (conditions[condition].field == field)
                                conditionsToReturn.push(conditions[condition]);
                        }
                    }
                    return conditionsToReturn;
                }
    
                function encodeCondition(condition) {
                    var output = "";
                    if (condition.hasOwnProperty("left") && condition.left) {
                        output += encodeCondition(condition.left);
                    }
                    if (condition.hasOwnProperty("right") && condition.right) {
                        var right = encodeCondition(condition.right);
                        if (right.length > 0) {
                            output += "^" + condition.type + right;
                        }
                    }
                    if (condition.field) {
                        output += condition.field;
                        output += condition.operator;
                        if (condition.value !== null && typeof condition.value !== "undefined")
                            output += condition.value;
                    }
                    return output;
                }
    
                function createEncodedQuery() {
                    var eq = "";
                    var ca = that.conditions;
                    for (var i = 0; i < ca.length; i++) {
                        var condition = ca[i];
                        if (eq.length)
                            eq += '^';
                        eq += encodeCondition(condition);
                    }
                    eq += "^EQ";
                    return eq;
                }
                that.addCondition = addCondition;
                that.newCondition = newCondition;
                that.createEncodedQuery = createEncodedQuery;
                that.getConditionsByField = getConditionsByField;
                that.removeCondition = removeCondition;
                return that;
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/glide/service.filterExpressionParser.js */
    angular.module('sn.common.glide').factory('filterExpressionParser', function() {
        'use strict';
        var operatorExpressions = [{
            wildcardExp: '(.*)',
            operator: 'STARTSWITH',
            toExpression: function(filter) {
                return filter;
            }
        }, {
            wildcardExp: '^\\*(.*)',
            operator: 'LIKE',
            toExpression: function(filter) {
                return (filter === '*' ? filter : '*' + filter);
            }
        }, {
            wildcardExp: '^\\.(.*)',
            operator: 'LIKE',
            toExpression: function(filter) {
                return '.' + filter;
            }
        }, {
            wildcardExp: '^%(.*)',
            operator: 'ENDSWITH',
            toExpression: function(filter) {
                return (filter === '%' ? filter : '%' + filter);
            }
        }, {
            wildcardExp: '(.*)%',
            operator: 'LIKE',
            toExpression: function(filter) {
                return filter + '%';
            }
        }, {
            wildcardExp: '^=(.*)',
            operator: '=',
            toExpression: function(filter) {
                return (filter === '=' ? filter : '=' + filter);
            }
        }, {
            wildcardExp: '^!\\*(.*)',
            operator: 'NOT LIKE',
            toExpression: function(filter) {
                return (filter === '!*' || filter === '!' ? filter : '!*' + filter);
            }
        }, {
            wildcardExp: '^!=(.*)',
            operator: '!=',
            toExpression: function(filter) {
                return (filter === '!=' || filter === '!' ? filter : '!=' + filter);
            }
        }];
        return {
            getOperatorExpressionForOperator: function(operator) {
                for (var i = 0; i < operatorExpressions.length; i++) {
                    var item = operatorExpressions[i];
                    if (item.operator === operator)
                        return item;
                }
                throw {
                    name: 'OperatorNotSupported',
                    message: 'The operator ' + operator + ' is not in the list of operatorExpressions.'
                };
            },
            parse: function(val, defaultOperator) {
                var parsedValue = {
                    filterText: val,
                    operator: defaultOperator || 'STARTSWITH'
                };
                for (var i = 1; i < operatorExpressions.length; i++) {
                    var operatorItem = operatorExpressions[i];
                    var match = val.match(operatorItem.wildcardExp);
                    if (match && match[1] !== '') {
                        parsedValue.operator = operatorItem.operator;
                        parsedValue.filterText = match[1];
                    }
                }
                return parsedValue;
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/glide/service.userPreferences.js */
    angular.module('sn.common.glide').factory("userPreferences", function($http, $q, unwrappedHTTPPromise, urlTools) {
        "use strict";
        var preferencesCache = {};
    
        function getPreference(preferenceName) {
            if (preferenceName in preferencesCache)
                return preferencesCache[preferenceName];
            var targetURL = urlTools.getURL('user_preference', {
                    "sysparm_pref_name": preferenceName,
                    "sysparm_action": "get"
                }),
                deferred = $q.defer();
            $http.get(targetURL).success(function(response) {
                deferred.resolve(response.sysparm_pref_value);
            }).error(function(data, status) {
                deferred.reject("Error getting preference " + preferenceName + ": " + status);
            });
            preferencesCache[preferenceName] = deferred.promise;
            return deferred.promise;
        }
    
        function setPreference(preferenceName, preferenceValue) {
            var targetURL = urlTools.getURL('user_preference', {
                "sysparm_pref_name": preferenceName,
                "sysparm_action": "set",
                "sysparm_pref_value": "" + preferenceValue
            });
            var httpPromise = $http.get(targetURL);
            addToCache(preferenceName, preferenceValue);
            return unwrappedHTTPPromise(httpPromise);
        }
    
        function addToCache(preferenceName, preferenceValue) {
            preferencesCache[preferenceName] = $q.when(preferenceValue);
        }
        var userPreferences = {
            getPreference: getPreference,
            setPreference: setPreference,
            addToCache: addToCache
        };
        return userPreferences;
    });;
    /*! RESOURCE: /scripts/sn/common/glide/service.nowStream.js */
    angular.module('sn.common.glide').constant('nowStreamTimerInterval', 5000);
    angular.module('sn.common.glide').factory('nowStream', function($q, $timeout, urlTools, nowStreamTimerInterval, snResource, $log) {
        'use strict';
        var Stream = function() {
            this.initialize.apply(this, arguments);
        };
        Stream.prototype = {
            initialize: function(table, query, sys_id, processor, interval, source, includeAttachments) {
                this.table = table;
                this.query = query;
                this.sysparmQuery = null;
                this.sys_id = sys_id;
                this.processor = processor;
                this.lastTimestamp = 0;
                this.inflightRequest = null;
                this.requestImmediateUpdate = false;
                this.interval = interval;
                this.source = source;
                this.includeAttachments = includeAttachments;
                this.stopped = true;
            },
            setQuery: function(sysparmQuery) {
                this.sysparmQuery = sysparmQuery;
            },
            poll: function(callback, preRequestCallback) {
                this.callback = callback;
                this.preRequestCallback = preRequestCallback;
                this._stopPolling();
                this._startPolling();
            },
            tap: function() {
                if (!this.inflightRequest) {
                    this._stopPolling();
                    this._startPolling();
                } else
                    this.requestImmediateUpdate = true;
            },
            insert: function(field, text) {
                this.insertForEntry(field, text, this.table, this.sys_id);
            },
            insertForEntry: function(field, text, table, sys_id) {
                return this.insertEntries([{
                    field: field,
                    text: text
                }], table, sys_id);
            },
            expandMentions: function(entryText, mentionIDMap) {
                return entryText.replace(/@\[(.+?)\]/gi, function(mention) {
                    var mentionedName = mention.substring(2, mention.length - 1);
                    if (mentionIDMap[mentionedName]) {
                        return "@[" + mentionIDMap[mentionedName] + ":" + mentionedName + "]";
                    } else {
                        return mention;
                    }
                });
            },
            insertEntries: function(entries, table, sys_id, mentionIDMap) {
                mentionIDMap = mentionIDMap || {};
                var sanitizedEntries = [];
                for (var i = 0; i < entries.length; i++) {
                    var entryText = entries[i].text;
                    if (entryText && entryText.endsWith('\n'))
                        entryText = entryText.substring(0, entryText.length - 1);
                    if (!entryText)
                        continue;
                    entries[i].text = this.expandMentions(entryText, mentionIDMap);
                    sanitizedEntries.push(entries[i]);
                }
                if (sanitizedEntries.length === 0)
                    return;
                this._isInserting = true;
                var url = this._getInsertURL(table, sys_id);
                var that = this;
                return snResource().post(url, {
                    entries: sanitizedEntries
                }).then(this._successCallback.bind(this), function() {
                    $log.warn('Error submitting entries', sanitizedEntries);
                }).then(function() {
                    that._isInserting = false;
                });
            },
            cancel: function() {
                this._stopPolling();
            },
            _startPolling: function() {
                var interval = this._getInterval();
                var that = this;
                var successCallback = this._successCallback.bind(this);
                that.stopped = false;
    
                function runPoll() {
                    if (that._isInserting) {
                        establishNextRequest();
                        return;
                    }
                    if (!that.inflightRequest) {
                        that.inflightRequest = that._executeRequest();
                        that.inflightRequest.then(successCallback);
                        that.inflightRequest.finally(function() {
                            that.inflightRequest = null;
                            if (that.requestImmediateUpdate) {
                                that.requestImmediateUpdate = false;
                                establishNextRequest(0);
                            } else {
                                establishNextRequest();
                            }
                        });
                    }
                }
    
                function establishNextRequest(intervalOverride) {
                    if (that.stopped)
                        return;
                    intervalOverride = (parseFloat(intervalOverride) >= 0) ? intervalOverride : interval;
                    $timeout.cancel(that.timer);
                    that.timer = $timeout(runPoll, intervalOverride);
                }
                runPoll();
            },
            _stopPolling: function() {
                if (this.timer)
                    $timeout.cancel(this.timer);
                this.stopped = true;
            },
            _executeRequest: function() {
                var url = this._getURL();
                if (this.preRequestCallback) {
                    this.preRequestCallback();
                }
                return snResource().get(url);
            },
            _getURL: function() {
                var params = {
                    table: this.table,
                    action: this._getAction(),
                    sysparm_silent_request: true,
                    sysparm_auto_request: true,
                    sysparm_timestamp: this.lastTimestamp,
                    include_attachments: this.includeAttachments
                };
                if (this.sys_id) {
                    params['sys_id'] = this.sys_id;
                } else if (this.sysparmQuery) {
                    params['sysparm_query'] = this.sysparmQuery;
                }
                var url = urlTools.getURL(this.processor, params);
                if (!this.sys_id) {
                    url += "&p=" + this.query;
                }
                return url;
            },
            _getInsertURL: function(table, sys_id) {
                return urlTools.getURL(this.processor, {
                    action: 'insert',
                    table: table,
                    sys_id: sys_id,
                    sysparm_timestamp: this.timestamp || 0,
                    sysparm_source: this.source
                });
            },
            _successCallback: function(response) {
                var response = response.data;
                if (response.entries && response.entries.length) {
                    response.entries = this._filterOld(response.entries);
                    if (response.entries.length > 0) {
                        this.lastEntry = angular.copy(response.entries[0]);
                        this.lastTimestamp = response.sys_timestamp || response.entries[0].sys_timestamp;
                    }
                }
                this.callback.call(null, response);
            },
            _filterOld: function(entries) {
                for (var i = 0; i < entries.length; i++) {
                    if (entries[i].sys_timestamp == this.lastTimestamp) {
                        if (!angular.equals(this._makeComparable(entries[i]), this._makeComparable(this.lastEntry)))
                            continue;
                    }
                    if (entries[i].sys_timestamp <= this.lastTimestamp)
                        return entries.slice(0, i);
                }
                return entries;
            },
            _makeComparable: function(entry) {
                var copy = angular.copy(entry);
                delete copy.short_description;
                delete copy.display_value;
                return copy;
            },
            _getAction: function() {
                return this.sys_id ? 'get_new_entries' : 'get_set_entries';
            },
            _getInterval: function() {
                if (this.interval)
                    return this.interval;
                else if (window.NOW && NOW.stream_poll_interval)
                    return NOW.stream_poll_interval * 1000;
                else
                    return nowStreamTimerInterval;
            }
        };
        return {
            create: function(table, query, sys_id, processor, interval, source) {
                return new Stream(table, query, sys_id, processor, interval, source);
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/glide/service.nowServer.js */
    angular.module('sn.common.glide').factory('nowServer', function($http, $q, userPreferences, angularProcessorUrl, urlTools) {
        return {
            getBaseURL: function() {
                return angularProcessorUrl;
            },
            getPartial: function(scope, partial, parms, callback) {
                var url = this.getPartialURL(partial, parms);
                if (url === scope.url) {
                    callback.call();
                    return;
                }
                var fn = scope.$on('$includeContentLoaded', function() {
                    fn.call();
                    callback.call();
                });
                scope.url = url;
            },
            replaceView: function($location, newView) {
                var p = $location.path();
                var a = p.split("/");
                a[1] = newView;
                p = a.join("/");
                return p;
            },
            getPartialURL: urlTools.getPartialURL,
            getURL: urlTools.getURL,
            urlFor: urlTools.urlFor,
            getPropertyURL: urlTools.getPropertyURL,
            setPreference: userPreferences.setPreference,
            getPreference: userPreferences.getPreference
        }
    });;;
    /*! RESOURCE: /scripts/sn/common/util/js_includes_util.js */
    /*! RESOURCE: /scripts/sn/common/util/_module.js */
    angular.module('sn.common.util', ['sn.common.auth']);
    angular.module('sn.util', ['sn.common.util']);;
    /*! RESOURCE: /scripts/sn/common/util/service.dateUtils.js */
    angular.module('sn.common.util').factory('dateUtils', function() {
        var dateUtils = {
            SYS_DATE_FORMAT: "yyyy-MM-dd",
            SYS_TIME_FORMAT: "HH:mm:ss",
            SYS_DATE_TIME_FORMAT: "yyyy-MM-dd HH:mm:ss",
            MONTH_NAMES: new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
            DAY_NAMES: new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'),
            LZ: function(x) {
                return (x < 0 || x > 9 ? "" : "0") + x
            },
            isDate: function(val, format) {
                var date = this.getDateFromFormat(val, format);
                if (date == 0) {
                    return false;
                }
                return true;
            },
            compareDates: function(date1, dateformat1, date2, dateformat2) {
                var d1 = this.getDateFromFormat(date1, dateformat1);
                var d2 = this.getDateFromFormat(date2, dateformat2);
                if (d1 == 0 || d2 == 0) {
                    return -1;
                } else if (d1 > d2) {
                    return 1;
                }
                return 0;
            },
            formatDateServer: function(date, format) {
                var ga = new GlideAjax("DateTimeUtils");
                ga.addParam("sysparm_name", "formatCalendarDate");
                var browserOffset = date.getTimezoneOffset() * 60000;
                var utcTime = date.getTime() - browserOffset;
                var userDateTime = utcTime - g_tz_offset;
                ga.addParam("sysparm_value", userDateTime);
                ga.getXMLWait();
                return ga.getAnswer();
            },
            formatDate: function(date, format) {
                if (format.indexOf("z") > 0)
                    return this.formatDateServer(date, format);
                format = format + "";
                var result = "";
                var i_format = 0;
                var c = "";
                var token = "";
                var y = date.getYear() + "";
                var M = date.getMonth() + 1;
                var d = date.getDate();
                var E = date.getDay();
                var H = date.getHours();
                var m = date.getMinutes();
                var s = date.getSeconds();
                var yyyy, yy, MMM, MM, dd, hh, h, mm, ss, ampm, HH, H, KK, K, kk, k;
                var value = new Object();
                value["M"] = M;
                value["MM"] = this.LZ(M);
                value["MMM"] = this.MONTH_NAMES[M + 11];
                value["NNN"] = this.MONTH_NAMES[M + 11];
                value["MMMM"] = this.MONTH_NAMES[M - 1];
                value["d"] = d;
                value["dd"] = this.LZ(d);
                value["E"] = this.DAY_NAMES[E + 7];
                value["EE"] = this.DAY_NAMES[E];
                value["H"] = H;
                value["HH"] = this.LZ(H);
                if (format.indexOf('w') != -1) {
                    var wk = date.getWeek();
                    if (wk >= 52 && M == 1) {
                        y = date.getYear();
                        y--;
                        y = y + "";
                    }
                    if (wk == 1 && M == 12) {
                        y = date.getYear();
                        y++;
                        y = y + "";
                    }
                    value["w"] = wk;
                    value["ww"] = this.LZ(wk);
                }
                var dayOfWeek = (7 + (E + 1) - (g_first_day_of_week - 1)) % 7;
                if (dayOfWeek == 0)
                    dayOfWeek = 7;
                value["D"] = dayOfWeek;
                if (y.length < 4) {
                    y = "" + (y - 0 + 1900);
                }
                value["y"] = "" + y;
                value["yyyy"] = y;
                value["yy"] = y.substring(2, 4);
                if (H == 0) {
                    value["h"] = 12;
                } else if (H > 12) {
                    value["h"] = H - 12;
                } else {
                    value["h"] = H;
                }
                value["hh"] = this.LZ(value["h"]);
                if (H > 11) {
                    value["K"] = H - 12;
                } else {
                    value["K"] = H;
                }
                value["k"] = H + 1;
                value["KK"] = this.LZ(value["K"]);
                value["kk"] = this.LZ(value["k"]);
                if (H > 11) {
                    value["a"] = "PM";
                } else {
                    value["a"] = "AM";
                }
                value["m"] = m;
                value["mm"] = this.LZ(m);
                value["s"] = s;
                value["ss"] = this.LZ(s);
                while (i_format < format.length) {
                    c = format.charAt(i_format);
                    token = "";
                    while ((format.charAt(i_format) == c) && (i_format < format.length)) {
                        token += format.charAt(i_format++);
                    }
                    if (value[token] != null) {
                        result = result + value[token];
                    } else {
                        result = result + token;
                    }
                }
                return result;
            },
            _isInteger: function(val) {
                var digits = "1234567890";
                for (var i = 0; i < val.length; i++) {
                    if (digits.indexOf(val.charAt(i)) == -1) {
                        return false;
                    }
                }
                return true;
            },
            _getInt: function(str, i, minlength, maxlength) {
                for (var x = maxlength; x >= minlength; x--) {
                    var token = str.substring(i, i + x);
                    if (token.length < minlength) {
                        return null;
                    }
                    if (this._isInteger(token)) {
                        return token;
                    }
                }
                return null;
            },
            getDateFromFormat: function(val, format) {
                val = val + "";
                format = format + "";
                var i_val = 0;
                var i_format = 0;
                var c = "";
                var token = "";
                var token2 = "";
                var x, y;
                var now = new Date();
                var year = now.getYear();
                var month = now.getMonth() + 1;
                var date = 0;
                var hh = now.getHours();
                var mm = now.getMinutes();
                var ss = now.getSeconds();
                var ampm = "";
                var week = false;
                while (i_format < format.length) {
                    c = format.charAt(i_format);
                    token = "";
                    while ((format.charAt(i_format) == c) && (i_format < format.length)) {
                        token += format.charAt(i_format++);
                    }
                    if (token == "yyyy" || token == "yy" || token == "y") {
                        if (token == "yyyy") {
                            x = 4;
                            y = 4;
                        }
                        if (token == "yy") {
                            x = 2;
                            y = 2;
                        }
                        if (token == "y") {
                            x = 2;
                            y = 4;
                        }
                        year = this._getInt(val, i_val, x, y);
                        if (year == null) {
                            return 0;
                        }
                        i_val += year.length;
                        if (year.length == 2) {
                            if (year > 70) {
                                year = 1900 + (year - 0);
                            } else {
                                year = 2000 + (year - 0);
                            }
                        }
                    } else if (token == "MMM" || token == "NNN") {
                        month = 0;
                        for (var i = 0; i < this.MONTH_NAMES.length; i++) {
                            var month_name = this.MONTH_NAMES[i];
                            if (val.substring(i_val, i_val + month_name.length).toLowerCase() == month_name.toLowerCase()) {
                                if (token == "MMM" || (token == "NNN" && i > 11)) {
                                    month = i + 1;
                                    if (month > 12) {
                                        month -= 12;
                                    }
                                    i_val += month_name.length;
                                    break;
                                }
                            }
                        }
                        if ((month < 1) || (month > 12)) {
                            return 0;
                        }
                    } else if (token == "EE" || token == "E") {
                        for (var i = 0; i < this.DAY_NAMES.length; i++) {
                            var day_name = this.DAY_NAMES[i];
                            if (val.substring(i_val, i_val + day_name.length).toLowerCase() == day_name.toLowerCase()) {
                                if (week) {
                                    if (i == 0 || i == 7)
                                        date += 6;
                                    else if (i == 2 || i == 9)
                                        date += 1;
                                    else if (i == 3 || i == 10)
                                        date += 2;
                                    else if (i == 4 || i == 11)
                                        date += 3;
                                    else if (i == 5 || i == 12)
                                        date += 4;
                                    else if (i == 6 || i == 13)
                                        date += 5;
                                }
                                i_val += day_name.length;
                                break;
                            }
                        }
                    } else if (token == "MM" || token == "M") {
                        month = this._getInt(val, i_val, token.length, 2);
                        if (month == null || (month < 1) || (month > 12)) {
                            return 0;
                        }
                        i_val += month.length;
                    } else if (token == "dd" || token == "d") {
                        date = this._getInt(val, i_val, token.length, 2);
                        if (date == null || (date < 1) || (date > 31)) {
                            return 0;
                        }
                        i_val += date.length;
                    } else if (token == "hh" || token == "h") {
                        hh = this._getInt(val, i_val, token.length, 2);
                        if (hh == null || (hh < 1) || (hh > 12)) {
                            return 0;
                        }
                        i_val += hh.length;
                    } else if (token == "HH" || token == "H") {
                        hh = this._getInt(val, i_val, token.length, 2);
                        if (hh == null || (hh < 0) || (hh > 23)) {
                            return 0;
                        }
                        i_val += hh.length;
                    } else if (token == "KK" || token == "K") {
                        hh = this._getInt(val, i_val, token.length, 2);
                        if (hh == null || (hh < 0) || (hh > 11)) {
                            return 0;
                        }
                        i_val += hh.length;
                    } else if (token == "kk" || token == "k") {
                        hh = this._getInt(val, i_val, token.length, 2);
                        if (hh == null || (hh < 1) || (hh > 24)) {
                            return 0;
                        }
                        i_val += hh.length;
                        hh--;
                    } else if (token == "mm" || token == "m") {
                        mm = this._getInt(val, i_val, token.length, 2);
                        if (mm == null || (mm < 0) || (mm > 59)) {
                            return 0;
                        }
                        i_val += mm.length;
                    } else if (token == "ss" || token == "s") {
                        ss = this._getInt(val, i_val, token.length, 2);
                        if (ss == null || (ss < 0) || (ss > 59)) {
                            return 0;
                        }
                        i_val += ss.length;
                    } else if (token == "a") {
                        if (val.substring(i_val, i_val + 2).toLowerCase() == "am") {
                            ampm = "AM";
                        } else if (val.substring(i_val, i_val + 2).toLowerCase() == "pm") {
                            ampm = "PM";
                        } else {
                            return 0;
                        }
                        i_val += 2;
                    } else if (token == "w" || token == "ww") {
                        var weekNum = this._getInt(val, i_val, token.length, 2);
                        week = true;
                        if (weekNum != null) {
                            var temp = new Date(year, 0, 1, 0, 0, 0);
                            temp.setWeek(parseInt(weekNum, 10));
                            year = temp.getFullYear();
                            month = temp.getMonth() + 1;
                            date = temp.getDate();
                        }
                        weekNum += "";
                        i_val += weekNum.length;
                    } else if (token == "D") {
                        if (week) {
                            var day = this._getInt(val, i_val, token.length, 1);
                            if ((day == null) || (day <= 0) || (day > 7))
                                return 0;
                            var temp = new Date(year, month - 1, date, hh, mm, ss);
                            var dayOfWeek = temp.getDay();
                            day = parseInt(day, 10);
                            day = (day + g_first_day_of_week - 1) % 7;
                            if (day == 0)
                                day = 7;
                            day--;
                            if (day < dayOfWeek)
                                day = 7 - (dayOfWeek - day);
                            else
                                day -= dayOfWeek;
                            if (day > 0) {
                                temp.setDate(temp.getDate() + day);
                                year = temp.getFullYear();
                                month = temp.getMonth() + 1;
                                date = temp.getDate();
                            }
                            i_val++;
                        }
                    } else if (token == "z")
                        i_val += 3;
                    else {
                        if (val.substring(i_val, i_val + token.length) != token) {
                            return 0;
                        } else {
                            i_val += token.length;
                        }
                    }
                }
                if (i_val != val.length) {
                    return 0;
                }
                if (month == 2) {
                    if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
                        if (date > 29) {
                            return 0;
                        }
                    } else {
                        if (date > 28) {
                            return 0;
                        }
                    }
                }
                if ((month == 4) || (month == 6) || (month == 9) || (month == 11)) {
                    if (date > 30) {
                        return 0;
                    }
                }
                if (hh < 12 && ampm == "PM") {
                    hh = hh - 0 + 12;
                } else if (hh > 11 && ampm == "AM") {
                    hh -= 12;
                }
                var newdate = new Date(year, month - 1, date, hh, mm, ss);
                return newdate.getTime();
            },
            parseDate: function(val) {
                var preferEuro = (arguments.length == 2) ? arguments[1] : false;
                generalFormats = new Array('y-M-d', 'MMM d, y', 'MMM d,y', 'y-MMM-d', 'd-MMM-y', 'MMM d');
                monthFirst = new Array('M/d/y', 'M-d-y', 'M.d.y', 'MMM-d', 'M/d', 'M-d');
                dateFirst = new Array('d/M/y', 'd-M-y', 'd.M.y', 'd-MMM', 'd/M', 'd-M');
                yearFirst = new Array('yyyyw.F', 'yyw.F');
                var checkList = new Array('generalFormats', preferEuro ? 'dateFirst' : 'monthFirst', preferEuro ? 'monthFirst' : 'dateFirst', 'yearFirst');
                var d = null;
                for (var i = 0; i < checkList.length; i++) {
                    var l = window[checkList[i]];
                    for (var j = 0; j < l.length; j++) {
                        d = this.getDateFromFormat(val, l[j]);
                        if (d != 0) {
                            return new Date(d);
                        }
                    }
                }
                return null;
            }
        };
        Date.prototype.getWeek = function() {
            var newYear = new Date(this.getFullYear(), 0, 1);
            var day = newYear.getDay() - (g_first_day_of_week - 1);
            day = (day >= 0 ? day : day + 7);
            var dayNum = Math.floor((this.getTime() - newYear.getTime() - (this.getTimezoneOffset() - newYear.getTimezoneOffset()) * 60000) / 86400000) + 1;
            var weekNum;
            if (day < 4) {
                weekNum = Math.floor((dayNum + day - 1) / 7) + 1;
                if (weekNum > 52)
                    weekNum = this._checkNextYear(weekNum);
                return weekNum;
            }
            weekNum = Math.floor((dayNum + day - 1) / 7);
            if (weekNum < 1)
                weekNum = this._lastWeekOfYear();
            else if (weekNum > 52)
                weekNum = this._checkNextYear(weekNum);
            return weekNum;
        };
        Date.prototype._lastWeekOfYear = function() {
            var newYear = new Date(this.getFullYear() - 1, 0, 1);
            var endOfYear = new Date(this.getFullYear() - 1, 11, 31);
            var day = newYear.getDay() - (g_first_day_of_week - 1);
            var dayNum = Math.floor((endOfYear.getTime() - newYear.getTime() - (endOfYear.getTimezoneOffset() - newYear.getTimezoneOffset()) * 60000) / 86400000) + 1;
            return day < 4 ? Math.floor((dayNum + day - 1) / 7) + 1 : Math.floor((dayNum + day - 1) / 7);
        };
        Date.prototype._checkNextYear = function() {
            var nYear = new Date(this.getFullYear() + 1, 0, 1);
            var nDay = nYear.getDay() - (g_first_day_of_week - 1);
            nDay = nDay >= 0 ? nDay : nDay + 7;
            return nDay < 4 ? 1 : 53;
        };
        Date.prototype.setWeek = function(weekNum) {
            weekNum--;
            var startOfYear = new Date(this.getFullYear(), 0, 1);
            var day = startOfYear.getDay() - (g_first_day_of_week - 1);
            if (day > 0 && day < 4) {
                this.setFullYear(startOfYear.getFullYear() - 1);
                this.setDate(31 - day + 1);
                this.setMonth(11);
            } else if (day > 3)
                this.setDate(startOfYear.getDate() + (7 - day));
            this.setDate(this.getDate() + (7 * weekNum));
        };
        return dateUtils;
    });
    /*! RESOURCE: /scripts/sn/common/util/service.debounceFn.js */
    angular.module("sn.common.util").service("debounceFn", function() {
        "use strict";
    
        function debounce(func, wait, immediate) {
            var timeout;
            return function() {
                var context = this,
                    args = arguments;
                var later = function() {
                    timeout = null;
                    if (!immediate) func.apply(context, args);
                };
                var callNow = immediate && !timeout;
                clearTimeout(timeout);
                timeout = setTimeout(later, wait);
                if (callNow) func.apply(context, args);
            };
        }
        return {
            debounce: debounce
        }
    });;
    /*! RESOURCE: /scripts/sn/common/util/factory.unwrappedHTTPPromise.js */
    angular.module('sn.common.util').factory("unwrappedHTTPPromise", function($q) {
        "use strict";
    
        function isGenericPromise(promise) {
            return (typeof promise.then === "function" &&
                promise.success === undefined &&
                promise.error === undefined);
        }
        return function(httpPromise) {
            if (isGenericPromise(httpPromise))
                return httpPromise;
            var deferred = $q.defer();
            httpPromise.success(function(data) {
                deferred.resolve(data);
            }).error(function(data, status) {
                deferred.reject({
                    data: data,
                    status: status
                })
            });
            return deferred.promise;
        };
    });;
    /*! RESOURCE: /scripts/sn/common/util/service.urlTools.js */
    angular.module('sn.common.util').constant('angularProcessorUrl', 'angular.do?sysparm_type=');
    angular.module('sn.common.util').factory("urlTools", function(getTemplateUrl, angularProcessorUrl) {
        "use strict";
    
        function getPartialURL(name, parameters) {
            var url = getTemplateUrl(name);
            if (parameters) {
                if (typeof parameters !== 'string') {
                    parameters = encodeURIParameters(parameters);
                }
                if (parameters.length) {
                    url += "&" + parameters;
                }
            }
            if (window.NOW && window.NOW.ng_cache_defeat)
                url += "&t=" + new Date().getTime();
            return url;
        }
    
        function getURL(name, parameters) {
            if (parameters && typeof parameters === 'object')
                return urlFor(name, parameters);
            var url = angularProcessorUrl;
            url += name;
            if (parameters)
                url += "&" + parameters;
            return url;
        }
    
        function urlFor(route, parameters) {
            var p = encodeURIParameters(parameters);
            return angularProcessorUrl + route + (p.length ? '&' + p : '');
        }
    
        function getPropertyURL(name) {
            var url = angularProcessorUrl + "get_property&name=" + name;
            url += "&t=" + new Date().getTime();
            return url;
        }
    
        function encodeURIParameters(parameters) {
            var s = [];
            for (var parameter in parameters) {
                if (parameters.hasOwnProperty(parameter)) {
                    var key = encodeURIComponent(parameter);
                    var value = parameters[parameter] ? encodeURIComponent(parameters[parameter]) : '';
                    s.push(key + "=" + value);
                }
            }
            return s.join('&');
        }
    
        function parseQueryString(qs) {
            qs = qs || '';
            if (qs.charAt(0) === '?') {
                qs = qs.substr(1);
            }
            var a = qs.split('&');
            if (a === "") {
                return {};
            }
            if (a && a[0].indexOf('http') != -1)
                a[0] = a[0].split("?")[1];
            var b = {};
            for (var i = 0; i < a.length; i++) {
                var p = a[i].split('=', 2);
                if (p.length == 1) {
                    b[p[0]] = "";
                } else {
                    b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
                }
            }
            return b;
        }
        return {
            getPartialURL: getPartialURL,
            getURL: getURL,
            urlFor: urlFor,
            getPropertyURL: getPropertyURL,
            encodeURIParameters: encodeURIParameters,
            parseQueryString: parseQueryString
        };
    });;
    /*! RESOURCE: /scripts/sn/common/util/service.getTemplateUrl.js */
    angular.module('sn.common.util').provider('getTemplateUrl', function(angularProcessorUrl) {
        'use strict';
        var _handlerId = 0;
        var _handlers = {};
        this.registerHandler = function(handler) {
            var registeredId = _handlerId;
            _handlers[_handlerId] = handler;
            _handlerId++;
            return function() {
                delete _handlers[registeredId];
            };
        };
        this.$get = function() {
            return getTemplateUrl;
        };
    
        function getTemplateUrl(templatePath) {
            if (_handlerId > 0) {
                var path;
                var handled = false;
                angular.forEach(_handlers, function(handler) {
                    if (!handled) {
                        var handlerPath = handler(templatePath);
                        if (typeof handlerPath !== 'undefined') {
                            path = handlerPath;
                            handled = true;
                        }
                    }
                });
                if (handled) {
                    return path;
                }
            }
            return angularProcessorUrl + 'get_partial&name=' + templatePath;
        }
    });;
    /*! RESOURCE: /scripts/sn/common/util/service.snTabActivity.js */
    angular.module("sn.common.util").service("snTabActivity", function($window, $timeout, $rootElement, $document) {
        "use strict";
        var activeEvents = ["keydown", "DOMMouseScroll", "mousewheel", "mousedown", "touchstart", "mousemove", "mouseenter", "input", "focus", "scroll"],
            defaultIdle = 75000,
            isPrimary = true,
            idleTime = 0,
            isVisible = true,
            idleTimeout = void(0),
            pageIdleTimeout = void(0),
            hasActed = false,
            appName = $rootElement.attr('ng-app') || "",
            storageKey = "sn.tabs." + appName + ".activeTab";
        var callbacks = {
            "tab.primary": [],
            "tab.secondary": [],
            "activity.active": [],
            "activity.idle": [{
                delay: defaultIdle,
                cb: function() {}
            }]
        };
        $window.tabGUID = $window.tabGUID || createGUID();
    
        function setAppName(an) {
            appName = an;
            storageKey = "sn.tabs." + appName + ".activeTab";
            makePrimary(true);
        }
    
        function createGUID(l) {
            l = l || 32;
            var strResult = '';
            while (strResult.length < l)
                strResult += (((1 + Math.random() + new Date().getTime()) * 0x10000) | 0).toString(16).substring(1);
            return strResult.substr(0, l);
        }
    
        function ngObjectIndexOf(arr, obj) {
            for (var i = 0, len = arr.length; i < len; i++)
                if (angular.equals(arr[i], obj))
                    return i;
            return -1;
        }
        var detectedApi,
            apis = [{
                eventName: 'visibilitychange',
                propertyName: 'hidden'
            }, {
                eventName: 'mozvisibilitychange',
                propertyName: 'mozHidden'
            }, {
                eventName: 'msvisibilitychange',
                propertyName: 'msHidden'
            }, {
                eventName: 'webkitvisibilitychange',
                propertyName: 'webkitHidden'
            }];
        apis.some(function(api) {
            if (angular.isDefined($document[0][api.propertyName])) {
                detectedApi = api;
                return true;
            }
        });
        if (detectedApi)
            $document.on(detectedApi.eventName, function() {
                if (!$document[0][detectedApi.propertyName]) {
                    makePrimary();
                    isVisible = true;
                } else {
                    if (!idleTimeout && !idleTime)
                        waitForIdle(0);
                    isVisible = false;
                }
            });
        angular.element($window).on({
            "mouseleave": function(e) {
                var destination = angular.isUndefined(e.toElement) ? e.relatedTarget : e.toElement;
                if (destination === null && $document[0].hasFocus()) {
                    waitForIdle(0);
                }
            },
            "storage": function(e) {
                if (e.originalEvent.key !== storageKey)
                    return;
                if ($window.localStorage.getItem(storageKey) !== $window.tabGUID)
                    makeSecondary();
            }
        });
    
        function waitForIdle(index, delayOffset) {
            var callback = callbacks['activity.idle'][index];
            var numCallbacks = callbacks['activity.idle'].length;
            delayOffset = delayOffset || callback.delay;
            angular.element($window).off(activeEvents.join(".snTabActivity "));
            angular.element($window).one(activeEvents.join(".snTabActivity "), setActive);
            if (index >= numCallbacks)
                return;
            if (idleTimeout)
                $timeout.cancel(idleTimeout);
            idleTimeout = $timeout(function() {
                idleTime = callback.delay;
                callback.cb();
                $timeout.cancel(idleTimeout);
                idleTimeout = void(0);
                angular.element($window).off(activeEvents.join(".snTabActivity "));
                angular.element($window).one(activeEvents.join(".snTabActivity "), setActive);
                for (var i = index + 1; i < numCallbacks; i++) {
                    var nextDelay = callbacks['activity.idle'][i].delay;
                    if (nextDelay <= callback.delay)
                        callbacks['activity.idle'][i].cb();
                    else {
                        waitForIdle(i, nextDelay - callback.delay);
                        break;
                    }
                }
            }, delayOffset, false);
        }
    
        function setActive() {
            angular.element($window).off(activeEvents.join(".snTabActivity "));
            if (idleTimeout) {
                $timeout.cancel(idleTimeout);
                idleTimeout = void(0);
            }
            var activeCallbacks = callbacks['activity.active'];
            activeCallbacks.some(function(callback) {
                if (callback.delay <= idleTime)
                    callback.cb();
                else
                    return true;
            });
            idleTime = 0;
            makePrimary();
            if (pageIdleTimeout) {
                $timeout.cancel(pageIdleTimeout);
                pageIdleTimeout = void(0);
            }
            var minDelay = callbacks['activity.idle'][0].delay;
            hasActed = false;
            if (!pageIdleTimeout)
                pageIdleTimeout = $timeout(pageIdleHandler, minDelay, false);
            listenForActivity();
        }
    
        function pageIdleHandler() {
            if (idleTimeout)
                return;
            var minDelay = callbacks['activity.idle'][0].delay;
            if (hasActed) {
                hasActed = false;
                if (pageIdleTimeout)
                    $timeout.cancel(pageIdleTimeout);
                pageIdleTimeout = $timeout(pageIdleHandler, minDelay, false);
                listenForActivity();
                return;
            }
            var delayOffset = minDelay;
            if (callbacks['activity.idle'].length > 1)
                delayOffset = callbacks['activity.idle'][1].delay - minDelay;
            idleTime = minDelay;
            callbacks['activity.idle'][0].cb();
            waitForIdle(1, delayOffset);
            pageIdleTimeout = void(0);
        }
    
        function listenForActivity() {
            angular.element($window).off(activeEvents.join(".snTabActivity "));
            angular.element($window).one(activeEvents.join(".snTabActivity "), onActivity);
            angular.element("#gsft_main").on("load.snTabActivity", function() {
                var src = angular.element(this).attr('src');
                if (src.indexOf("/") == 0 || src.indexOf($window.location.origin) == 0 || src.indexOf('http') == -1) {
                    var iframeWindow = this.contentWindow ? this.contentWindow : this.contentDocument.defaultView;
                    angular.element(iframeWindow).off(activeEvents.join(".snTabActivity "));
                    angular.element(iframeWindow).one(activeEvents.join(".snTabActivity "), onActivity);
                }
            });
            angular.element('iframe').each(function(idx, iframe) {
                var src = angular.element(iframe).attr('src');
                if (!src)
                    return;
                if (src.indexOf("/") == 0 || src.indexOf($window.location.origin) == 0 || src.indexOf('http') == -1) {
                    var iframeWindow = iframe.contentWindow ? iframe.contentWindow : iframe.contentDocument.defaultView;
                    angular.element(iframeWindow).off(activeEvents.join(".snTabActivity "));
                    angular.element(iframeWindow).one(activeEvents.join(".snTabActivity "), onActivity);
                }
            });
        }
    
        function onActivity() {
            hasActed = true;
            makePrimary();
        }
    
        function makePrimary(initial) {
            var oldGuid = $window.localStorage.getItem(storageKey);
            isPrimary = true;
            isVisible = true;
            $timeout.cancel(idleTimeout);
            idleTimeout = void(0);
            if (canUseStorage() && oldGuid !== $window.tabGUID && !initial)
                for (var i = 0, len = callbacks["tab.primary"].length; i < len; i++)
                    callbacks["tab.primary"][i].cb();
            try {
                $window.localStorage.setItem(storageKey, $window.tabGUID);
            } catch (ignored) {}
            if (idleTime && $document[0].hasFocus())
                setActive();
        }
    
        function makeSecondary() {
            isPrimary = false;
            isVisible = false;
            for (var i = 0, len = callbacks["tab.secondary"].length; i < len; i++)
                callbacks["tab.secondary"][i].cb();
        }
    
        function registerCallback(event, callback, scope) {
            var cbObject = angular.isObject(callback) ? callback : {
                delay: defaultIdle,
                cb: callback
            };
            if (callbacks[event]) {
                callbacks[event].push(cbObject);
                callbacks[event].sort(function(a, b) {
                    return a.delay - b.delay;
                })
            }
    
            function destroyCallback() {
                if (callbacks[event]) {
                    var pos = ngObjectIndexOf(callbacks[event], cbObject);
                    if (pos !== -1)
                        callbacks[event].splice(pos, 1);
                }
            }
            if (scope)
                scope.$on("$destroy", function() {
                    destroyCallback();
                });
            return destroyCallback;
        }
    
        function registerIdleCallback(options, onIdle, onReturn, scope) {
            var delay = options,
                onIdleDestroy,
                onReturnDestroy;
            if (angular.isObject(options)) {
                delay = options.delay;
                onIdle = options.onIdle || onIdle;
                onReturn = options.onReturn || onReturn;
                scope = options.scope || scope;
            }
            if (angular.isFunction(onIdle))
                onIdleDestroy = registerCallback("activity.idle", {
                    delay: delay,
                    cb: onIdle
                });
            else if (angular.isFunction(onReturn)) {
                onIdleDestroy = registerCallback("activity.idle", {
                    delay: delay,
                    cb: function() {}
                });
            }
            if (angular.isFunction(onReturn))
                onReturnDestroy = registerCallback("activity.active", {
                    delay: delay,
                    cb: onReturn
                });
    
            function destroyAll() {
                if (angular.isFunction(onIdleDestroy))
                    onIdleDestroy();
                if (angular.isFunction(onReturnDestroy))
                    onReturnDestroy();
            }
            if (scope)
                scope.$on("$destroy", function() {
                    destroyAll();
                });
            return destroyAll;
        }
    
        function canUseStorage() {
            var canWe = false;
            try {
                $window.localStorage.setItem(storageKey, $window.tabGUID);
                canWe = true;
            } catch (ignored) {}
            return canWe;
        }
        makePrimary(true);
        listenForActivity();
        pageIdleTimeout = $timeout(pageIdleHandler, defaultIdle, false);
        return {
            on: registerCallback,
            onIdle: registerIdleCallback,
            setAppName: setAppName,
            get isPrimary() {
                return isPrimary;
            },
            get isIdle() {
                return idleTime > 0;
            },
            get idleTime() {
                return idleTime;
            },
            get isVisible() {
                return isVisible;
            },
            get appName() {
                return appName;
            },
            get defaultIdleTime() {
                return defaultIdle
            },
            isActive: function() {
                return this.idleTime < this.defaultIdleTime && this.isVisible;
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/util/factory.ArraySynchronizer.js */
    angular.module("sn.common.util").factory("ArraySynchronizer", function() {
        'use strict';
    
        function ArraySynchronizer() {}
    
        function index(key, arr) {
            var result = {};
            var keys = [];
            result.orderedKeys = keys;
            angular.forEach(arr, function(item) {
                var keyValue = item[key];
                result[keyValue] = item;
                keys.push(keyValue);
            });
            return result;
        }
    
        function sortByKeyAndModel(arr, key, model) {
            arr.sort(function(a, b) {
                var aIndex = model.indexOf(a[key]);
                var bIndex = model.indexOf(b[key]);
                if (aIndex > bIndex)
                    return 1;
                else if (aIndex < bIndex)
                    return -1;
                return 0;
            });
        }
        ArraySynchronizer.prototype = {
            add: function(syncField, dest, source, end) {
                end = end || "bottom";
                var destIndex = index(syncField, dest);
                var sourceIndex = index(syncField, source);
                angular.forEach(sourceIndex.orderedKeys, function(key) {
                    if (destIndex.orderedKeys.indexOf(key) === -1) {
                        if (end === "bottom") {
                            dest.push(sourceIndex[key]);
                        } else {
                            dest.unshift(sourceIndex[key]);
                        }
                    }
                });
            },
            synchronize: function(syncField, dest, source, deepKeySyncArray) {
                var destIndex = index(syncField, dest);
                var sourceIndex = index(syncField, source);
                deepKeySyncArray = (typeof deepKeySyncArray === "undefined") ? [] : deepKeySyncArray;
                for (var i = destIndex.orderedKeys.length - 1; i >= 0; i--) {
                    var key = destIndex.orderedKeys[i];
                    if (sourceIndex.orderedKeys.indexOf(key) === -1) {
                        destIndex.orderedKeys.splice(i, 1);
                        dest.splice(i, 1);
                    }
                    if (deepKeySyncArray.length > 0) {
                        angular.forEach(deepKeySyncArray, function(deepKey) {
                            if (sourceIndex[key] && destIndex[key][deepKey] !== sourceIndex[key][deepKey]) {
                                destIndex[key][deepKey] = sourceIndex[key][deepKey];
                            }
                        });
                    }
                }
                angular.forEach(sourceIndex.orderedKeys, function(key) {
                    if (destIndex.orderedKeys.indexOf(key) === -1)
                        dest.push(sourceIndex[key]);
                });
                sortByKeyAndModel(dest, syncField, sourceIndex.orderedKeys);
            }
        };
        return ArraySynchronizer;
    });;
    /*! RESOURCE: /scripts/sn/common/util/directive.snBindOnce.js */
    angular.module("sn.common.util").directive("snBindOnce", function($sanitize) {
        "use strict";
        return {
            restrict: "A",
            link: function(scope, element, attrs) {
                var value = scope.$eval(attrs.snBindOnce);
                var sanitizedValue = $sanitize(value);
                element.append(sanitizedValue);
            }
        }
    });
    /*! RESOURCE: /scripts/sn/common/util/directive.snCloak.js */
    angular.module("sn.common.util").directive("snCloak", function() {
        "use strict";
        return {
            restrict: "A",
            compile: function(element, attr) {
                return function() {
                    attr.$set('snCloak', undefined);
                    element.removeClass('sn-cloak');
                }
            }
        };
    });
    /*! RESOURCE: /scripts/sn/common/util/service.md5.js */
    angular.module('sn.common.util').factory('md5', function() {
        'use strict';
        var md5cycle = function(x, k) {
            var a = x[0],
                b = x[1],
                c = x[2],
                d = x[3];
            a = ff(a, b, c, d, k[0], 7, -680876936);
            d = ff(d, a, b, c, k[1], 12, -389564586);
            c = ff(c, d, a, b, k[2], 17, 606105819);
            b = ff(b, c, d, a, k[3], 22, -1044525330);
            a = ff(a, b, c, d, k[4], 7, -176418897);
            d = ff(d, a, b, c, k[5], 12, 1200080426);
            c = ff(c, d, a, b, k[6], 17, -1473231341);
            b = ff(b, c, d, a, k[7], 22, -45705983);
            a = ff(a, b, c, d, k[8], 7, 1770035416);
            d = ff(d, a, b, c, k[9], 12, -1958414417);
            c = ff(c, d, a, b, k[10], 17, -42063);
            b = ff(b, c, d, a, k[11], 22, -1990404162);
            a = ff(a, b, c, d, k[12], 7, 1804603682);
            d = ff(d, a, b, c, k[13], 12, -40341101);
            c = ff(c, d, a, b, k[14], 17, -1502002290);
            b = ff(b, c, d, a, k[15], 22, 1236535329);
            a = gg(a, b, c, d, k[1], 5, -165796510);
            d = gg(d, a, b, c, k[6], 9, -1069501632);
            c = gg(c, d, a, b, k[11], 14, 643717713);
            b = gg(b, c, d, a, k[0], 20, -373897302);
            a = gg(a, b, c, d, k[5], 5, -701558691);
            d = gg(d, a, b, c, k[10], 9, 38016083);
            c = gg(c, d, a, b, k[15], 14, -660478335);
            b = gg(b, c, d, a, k[4], 20, -405537848);
            a = gg(a, b, c, d, k[9], 5, 568446438);
            d = gg(d, a, b, c, k[14], 9, -1019803690);
            c = gg(c, d, a, b, k[3], 14, -187363961);
            b = gg(b, c, d, a, k[8], 20, 1163531501);
            a = gg(a, b, c, d, k[13], 5, -1444681467);
            d = gg(d, a, b, c, k[2], 9, -51403784);
            c = gg(c, d, a, b, k[7], 14, 1735328473);
            b = gg(b, c, d, a, k[12], 20, -1926607734);
            a = hh(a, b, c, d, k[5], 4, -378558);
            d = hh(d, a, b, c, k[8], 11, -2022574463);
            c = hh(c, d, a, b, k[11], 16, 1839030562);
            b = hh(b, c, d, a, k[14], 23, -35309556);
            a = hh(a, b, c, d, k[1], 4, -1530992060);
            d = hh(d, a, b, c, k[4], 11, 1272893353);
            c = hh(c, d, a, b, k[7], 16, -155497632);
            b = hh(b, c, d, a, k[10], 23, -1094730640);
            a = hh(a, b, c, d, k[13], 4, 681279174);
            d = hh(d, a, b, c, k[0], 11, -358537222);
            c = hh(c, d, a, b, k[3], 16, -722521979);
            b = hh(b, c, d, a, k[6], 23, 76029189);
            a = hh(a, b, c, d, k[9], 4, -640364487);
            d = hh(d, a, b, c, k[12], 11, -421815835);
            c = hh(c, d, a, b, k[15], 16, 530742520);
            b = hh(b, c, d, a, k[2], 23, -995338651);
            a = ii(a, b, c, d, k[0], 6, -198630844);
            d = ii(d, a, b, c, k[7], 10, 1126891415);
            c = ii(c, d, a, b, k[14], 15, -1416354905);
            b = ii(b, c, d, a, k[5], 21, -57434055);
            a = ii(a, b, c, d, k[12], 6, 1700485571);
            d = ii(d, a, b, c, k[3], 10, -1894986606);
            c = ii(c, d, a, b, k[10], 15, -1051523);
            b = ii(b, c, d, a, k[1], 21, -2054922799);
            a = ii(a, b, c, d, k[8], 6, 1873313359);
            d = ii(d, a, b, c, k[15], 10, -30611744);
            c = ii(c, d, a, b, k[6], 15, -1560198380);
            b = ii(b, c, d, a, k[13], 21, 1309151649);
            a = ii(a, b, c, d, k[4], 6, -145523070);
            d = ii(d, a, b, c, k[11], 10, -1120210379);
            c = ii(c, d, a, b, k[2], 15, 718787259);
            b = ii(b, c, d, a, k[9], 21, -343485551);
            x[0] = add32(a, x[0]);
            x[1] = add32(b, x[1]);
            x[2] = add32(c, x[2]);
            x[3] = add32(d, x[3]);
        };
        var cmn = function(q, a, b, x, s, t) {
            a = add32(add32(a, q), add32(x, t));
            return add32((a << s) | (a >>> (32 - s)), b);
        };
        var ff = function(a, b, c, d, x, s, t) {
            return cmn((b & c) | ((~b) & d), a, b, x, s, t);
        };
        var gg = function(a, b, c, d, x, s, t) {
            return cmn((b & d) | (c & (~d)), a, b, x, s, t);
        };
        var hh = function(a, b, c, d, x, s, t) {
            return cmn(b ^ c ^ d, a, b, x, s, t);
        };
        var ii = function(a, b, c, d, x, s, t) {
            return cmn(c ^ (b | (~d)), a, b, x, s, t);
        };
        var md51 = function(s) {
            var txt = '';
            var n = s.length,
                state = [1732584193, -271733879, -1732584194, 271733878],
                i;
            for (i = 64; i <= s.length; i += 64) {
                md5cycle(state, md5blk(s.substring(i - 64, i)));
            }
            s = s.substring(i - 64);
            var tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
            for (i = 0; i < s.length; i++)
                tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
            tail[i >> 2] |= 0x80 << ((i % 4) << 3);
            if (i > 55) {
                md5cycle(state, tail);
                for (i = 0; i < 16; i++) tail[i] = 0;
            }
            tail[14] = n * 8;
            md5cycle(state, tail);
            return state;
        };
        var md5blk = function(s) {
            var md5blks = [],
                i;
            for (i = 0; i < 64; i += 4) {
                md5blks[i >> 2] = s.charCodeAt(i) +
                    (s.charCodeAt(i + 1) << 8) +
                    (s.charCodeAt(i + 2) << 16) +
                    (s.charCodeAt(i + 3) << 24);
            }
            return md5blks;
        };
        var hex_chr = '0123456789abcdef'.split('');
        var rhex = function(n) {
            var s = '',
                j = 0;
            for (; j < 4; j++)
                s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] +
                hex_chr[(n >> (j * 8)) & 0x0F];
            return s;
        };
        var hex = function(x) {
            for (var i = 0; i < x.length; i++)
                x[i] = rhex(x[i]);
            return x.join('');
        };
        var add32 = function(a, b) {
            return (a + b) & 0xFFFFFFFF;
        };
        return function(s) {
            return hex(md51(s));
        };
    });;
    /*! RESOURCE: /scripts/sn/common/util/service.priorityQueue.js */
    angular.module('sn.common.util').factory('priorityQueue', function() {
        'use strict';
        return function(comparator) {
            var items = [];
            var compare = comparator || function(a, b) {
                return a - b;
            };
            var swap = function(a, b) {
                var temp = items[a];
                items[a] = items[b];
                items[b] = temp;
            };
            var bubbleUp = function(pos) {
                var parent;
                while (pos > 0) {
                    parent = (pos - 1) >> 1;
                    if (compare(items[pos], items[parent]) >= 0)
                        break;
                    swap(parent, pos);
                    pos = parent;
                }
            };
            var bubbleDown = function(pos) {
                var left, right, min, last = items.length - 1;
                while (true) {
                    left = (pos << 1) + 1;
                    right = left + 1;
                    min = pos;
                    if (left <= last && compare(items[left], items[min]) < 0)
                        min = left;
                    if (right <= last && compare(items[right], items[min]) < 0)
                        min = right;
                    if (min === pos)
                        break;
                    swap(min, pos);
                    pos = min;
                }
            };
            return {
                add: function(item) {
                    items.push(item);
                    bubbleUp(items.length - 1);
                },
                poll: function() {
                    var first = items[0],
                        last = items.pop();
                    if (items.length > 0) {
                        items[0] = last;
                        bubbleDown(0);
                    }
                    return first;
                },
                peek: function() {
                    return items[0];
                },
                clear: function() {
                    items = [];
                },
                inspect: function() {
                    return angular.toJson(items, true);
                },
                get size() {
                    return items.length;
                },
                get all() {
                    return items;
                },
                set comparator(fn) {
                    compare = fn;
                }
            };
        };
    });;
    /*! RESOURCE: /scripts/sn/common/util/service.snResource.js */
    angular.module('sn.common.util').factory('snResource', function($http, $q, priorityQueue, md5) {
        'use strict';
        var methods = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'jsonp', 'trace'],
            queue = priorityQueue(function(a, b) {
                return a.timestamp - b.timestamp;
            }),
            resource = {},
            pendingRequests = [],
            inFlightRequests = [];
        return function() {
            var requestInterceptors = $http.defaults.transformRequest,
                responseInterceptors = $http.defaults.transformResponse;
            var next = function() {
                var request = queue.peek();
                pendingRequests.shift();
                inFlightRequests.push(request.hash);
                $http(request.config).then(function(response) {
                    request.deferred.resolve(response);
                }, function(reason) {
                    request.deferred.reject(reason);
                }).finally(function() {
                    queue.poll();
                    inFlightRequests.shift();
                    if (queue.size > 0)
                        next();
                });
            };
            angular.forEach(methods, function(method) {
                resource[method] = function(url, data) {
                    var deferredRequest = $q.defer(),
                        promise = deferredRequest.promise,
                        deferredAbort = $q.defer(),
                        config = {
                            method: method,
                            url: url,
                            data: data,
                            transformRequest: requestInterceptors,
                            transformResponse: responseInterceptors,
                            timeout: deferredAbort.promise
                        },
                        hash = md5(JSON.stringify(config));
                    pendingRequests.push(hash);
                    queue.add({
                        config: config,
                        deferred: deferredRequest,
                        timestamp: Date.now(),
                        hash: hash
                    });
                    if (queue.size === 1)
                        next();
                    promise.abort = function() {
                        deferredAbort.resolve('Request cancelled');
                    };
                    return promise;
                };
            });
            resource.addRequestInterceptor = function(fn) {
                requestInterceptors = requestInterceptors.concat([fn]);
            };
            resource.addResponseInterceptor = function(fn) {
                responseInterceptors = responseInterceptors.concat([fn]);
            };
            resource.queueSize = function() {
                return queue.size;
            };
            resource.queuedRequests = function() {
                return queue.all;
            };
            return resource;
        };
    });;
    /*! RESOURCE: /scripts/sn/common/util/service.snConnect.js */
    angular.module("sn.common.util").service("snConnectService", function($http, snCustomEvent) {
        "use strict";
        var connectPaths = ["/$c.do", "/$chat.do"];
    
        function canOpenInFrameset() {
            return window.top.NOW.collaborationFrameset;
        }
    
        function isInConnect() {
            var parentPath = getParentPath();
            return connectPaths.some(function(path) {
                return parentPath == path;
            });
        }
    
        function getParentPath() {
            try {
                return window.top.location.pathname;
            } catch (IGNORED) {
                return "";
            }
        }
    
        function openWithProfile(profile) {
            if (isInConnect() || canOpenInFrameset())
                snCustomEvent.fireTop('chat:open_conversation', profile);
            else
                window.open("$c.do#/with/" + profile.sys_id, "_blank");
        }
        return {
            openWithProfile: openWithProfile
        }
    });;
    /*! RESOURCE: /scripts/sn/common/util/snPolyfill.js */
    (function() {
        "use strict";
        polyfill(String.prototype, 'startsWith', function(prefix) {
            return this.indexOf(prefix) === 0;
        });
        polyfill(String.prototype, 'endsWith', function(suffix) {
            return this.indexOf(suffix, this.length - suffix.length) !== -1;
        });
        polyfill(Number, 'isNaN', function(value) {
            return value !== value;
        });
        polyfill(window, 'btoa', function(input) {
            var str = String(input);
            var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
            for (
                var block, charCode, idx = 0, map = chars, output = ''; str.charAt(idx | 0) || (map = '=', idx % 1); output += map.charAt(63 & block >> 8 - idx % 1 * 8)
            ) {
                charCode = str.charCodeAt(idx += 3 / 4);
                if (charCode > 0xFF) {
                    throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");
                }
                block = block << 8 | charCode;
            }
            return output;
        });
    
        function polyfill(obj, slot, fn) {
            if (obj[slot] === void(0)) {
                obj[slot] = fn;
            }
        }
        window.console = window.console || {
            log: function() {}
        };
    })();;
    /*! RESOURCE: /scripts/sn/common/util/directive.snFocus.js */
    angular.module('sn.common.util').directive('snFocus', function($timeout) {
        'use strict';
        return function(scope, element, attrs) {
            scope.$watch(attrs.snFocus, function(value) {
                if (value !== true)
                    return;
                $timeout(function() {
                    element[0].focus();
                });
            });
        };
    });;
    /*! RESOURCE: /scripts/sn/common/util/directive.snResizeHeight.js */
    angular.module('sn.common.util').directive('snResizeHeight', function($timeout) {
        "use strict";
        return {
            restrict: 'A',
            link: function(scope, elem, attrs) {
                var typographyStyles = [
                    'fontFamily',
                    'fontSize',
                    'fontWeight',
                    'fontStyle',
                    'letterSpacing',
                    'textTransform',
                    'wordSpacing',
                    'textIndent'
                ];
                var maxHeight = parseInt(elem.css('max-height'), 10) || 0;
                var offset = 0;
                if (elem.css('box-sizing') === 'border-box' || elem.css('-moz-box-sizing') === 'border-box' || elem.css('-webkit-box-sizing') === 'border-box')
                    offset = elem.outerHeight() - elem.height();
                var styles = {};
                angular.forEach(typographyStyles, function(val) {
                    styles[val] = elem.css(val);
                });
                var $clone = angular.element('<textarea rows="1" tabindex="-1" style="position:absolute; top:-999px; left:0; right:auto; bottom:auto; border:0; padding: 0; -moz-box-sizing:content-box; -webkit-box-sizing:content-box; box-sizing:content-box; word-wrap:break-word; height:0 !important; min-height:0 !important; overflow:hidden; transition:none; -webkit-transition:none; -moz-transition:none;"></textarea>');
                $clone.css(styles);
                $timeout(function() {
                    angular.element(document.body).append($clone);
                    reSize();
                }, 0, false);
                if (window.chrome) {
                    var width = elem[0].style.width;
                    elem[0].style.width = '0px';
                    var ignore = elem[0].offsetWidth;
                    elem[0].style.width = width;
                }
    
                function reSize() {
                    if (!setWidth())
                        return;
                    if (!elem[0].value && attrs['placeholder'])
                        $clone[0].value = attrs['placeholder'] || '';
                    else
                        $clone[0].value = elem[0].value;
                    $clone[0].scrollTop = 0;
                    $clone[0].scrollTop = 9e4;
                    var newHeight = $clone[0].scrollTop;
                    if (maxHeight && newHeight > maxHeight) {
                        newHeight = maxHeight;
                        elem[0].style.overflow = "auto";
                    } else
                        elem[0].style.overflow = "hidden";
                    newHeight += offset;
                    elem[0].style.height = newHeight + "px";
                }
    
                function setWidth() {
                    var width;
                    var style = window.getComputedStyle ? window.getComputedStyle(elem[0], null) : false;
                    if (style) {
                        width = elem[0].getBoundingClientRect().width;
                        if (width === 0 || typeof width !== 'number') {
                            if (style.width.length && style.width[style.width.length - 1] === '%') {
                                $timeout(reSize, 0, false);
                                return false;
                            }
                            width = parseInt(style.width, 10);
                        }
                        angular.forEach(['paddingLeft', 'paddingRight', 'borderLeftWidth', 'borderRightWidth'], function(val) {
                            width -= parseInt(style[val], 10);
                        });
                    } else {
                        width = Math.max(elem.width(), 0);
                    }
                    $clone[0].style.width = width + 'px';
                    return true;
                }
                scope.$watch(
                    function() {
                        return elem[0].value
                    },
                    function(newValue, oldValue) {
                        if (newValue === oldValue)
                            return;
                        reSize();
                    }
                );
                elem.on('input.resize', reSize);
                if (attrs['snResizeHeight'] == "trim") {
                    elem.on('blur', function() {
                        elem.val(elem.val().trim());
                        reSize();
                    });
                }
                scope.$on('$destroy', function() {
                    $clone.remove();
                });
            }
        }
    });;
    /*! RESOURCE: /scripts/sn/common/util/directive.snBlurOnEnter.js */
    angular.module('sn.common.util').directive('snBlurOnEnter', function() {
        'use strict';
        return function(scope, element) {
            element.bind("keydown keypress", function(event) {
                if (event.which !== 13)
                    return;
                element.blur();
                event.preventDefault();
            });
        };
    });;
    /*! RESOURCE: /scripts/sn/common/util/directive.snStickyHeaders.js */
    angular.module('sn.common.util').directive('snStickyHeaders', function() {
        "use strict";
        return {
            restrict: 'A',
            transclude: false,
            replace: false,
            link: function(scope, element, attrs) {
                element.addClass('sticky-headers');
                var containers;
                var scrollContainer = element.find('[sn-sticky-scroll-container]');
                scrollContainer.addClass('sticky-scroll-container');
    
                function refreshHeaders() {
                    if (attrs.snStickyHeaders !== 'false') {
                        angular.forEach(containers, function(container) {
                            var stickyContainer = angular.element(container);
                            var stickyHeader = stickyContainer.find('[sn-sticky-header]');
                            var stickyOffset = stickyContainer.position().top + stickyContainer.outerHeight();
                            stickyContainer.addClass('sticky-container');
                            if (stickyOffset < stickyContainer.outerHeight() && stickyOffset > -stickyHeader.outerHeight()) {
                                stickyContainer.css('padding-top', stickyHeader.outerHeight());
                                stickyHeader.css('width', stickyHeader.outerWidth());
                                stickyHeader.removeClass('sticky-header-disabled').addClass('sticky-header-enabled');
                            } else {
                                stickyContainer.css('padding-top', '');
                                stickyHeader.css('width', '');
                                stickyHeader.removeClass('sticky-header-enabled').addClass('sticky-header-disabled');
                            }
                        });
                    } else {
                        element.find('[sn-sticky-container]').removeClass('sticky-container');
                        element.find('[sn-sticky-container]').css('padding-top', '');
                        element.find('[sn-sticky-header]').css('width', '');
                        element.find('[sn-sticky-header]').removeClass('sticky-header-enabled').addClass('sticky-header-disabled');
                    }
                }
                scope.$watch(function() {
                    scrollContainer.find('[sn-sticky-header]').addClass('sticky-header');
                    containers = element.find('[sn-sticky-container]');
                    return attrs.snStickyHeaders;
                }, refreshHeaders);
                scope.$watch(function() {
                    return scrollContainer[0].scrollHeight;
                }, refreshHeaders);
                scrollContainer.on('scroll', refreshHeaders);
            }
        };
    });;;
    /*! RESOURCE: /scripts/sn/common/form/js_includes_form.js */
    /*! RESOURCE: /scripts/sn/common/form/_module.js */
    angular.module('sn.common.form', [
        'sn.common.clientScript'
    ]);;
    /*! RESOURCE: /scripts/sn/common/form/directive.glideFormField.js */
    angular.module('sn.common.form').directive('glideFormField', function(getTemplateUrl, cabrillo, glideFormFieldFactory, $log) {
        'use strict';
        return {
            restrict: 'E',
            templateUrl: getTemplateUrl('directive_glide_form_field.xml'),
            scope: {
                field: '=',
                tableName: '=',
                getGlideForm: '&glideForm'
            },
            controller: function($element, $scope) {
                var g_form;
                if (!$scope.getGlideForm) {
                    $log.warn('glideFormField: Field directive is missing GlideForm');
                } else {
                    g_form = $scope.getGlideForm();
                }
                var field = $scope.field;
                var glideField = glideFormFieldFactory.create(field);
                $scope.isReadonly = glideField.isReadonly;
                $scope.isMandatory = glideField.isMandatory;
                $scope.isVisible = glideField.isVisible;
                $scope.hasMessages = glideField.hasMessages;
                var isNative = cabrillo.isNative();
                $scope.showBarcodeHelper = isNative && glideField.hasBarcodeHelper();
                $scope.showCurrentLocationHelper = isNative && glideField.hasCurrentLocationHelper();
                $scope.getBarcode = function() {
                    cabrillo.camera.getBarcode().then(function(value) {
                        cabrillo.log('Received barcode value: ' + value);
                        g_form.setValue($scope.field.name, value);
                    });
                };
                $scope.getCurrentLocation = function() {
                    cabrillo.geolocation.getCurrentLocation().then(function(value) {
                        var composite = value.coordinate.latitude + ',' + value.coordinate.longitude;
                        g_form.setValue($scope.field.name, composite);
                    });
                };
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/form/directive.recursiveHelper.js */
    angular.module('sn.common.form').directive('recursiveHelper', function($compile) {
        return {
            restrict: "EACM",
            priority: 100000,
            compile: function(tElement, tAttr) {
                var contents = tElement.contents().remove();
                var compiledContents;
                return function(scope, iElement, iAttr) {
                    if (!compiledContents)
                        compiledContents = $compile(contents);
                    iElement.append(compiledContents(scope, function(clone) {
                        return clone;
                    }));
                };
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/form/glideUIActionsFactory.js */
    angular.module('sn.common.form').factory('glideUIActionsFactory', function(urlTools, $http, $q, $log) {
        'use strict';
        var ACTION_OPERATIONS = {
            'INSERT': 'insert',
            'UPDATE': 'update'
        };
        var ACTION_TYPES = {
            'LIST': 'list',
            'FORM': 'form'
        };
        var ACTION_DISPLAY_TYPES = {
            'LIST_BUTTON': 'list_button',
            'FORM_BUTTON': 'form_button',
            'FORM_MORE_ITEM': 'form_more_item'
        };
        return {
            ACTION_OPERATIONS: ACTION_OPERATIONS,
            ACTION_TYPES: ACTION_TYPES,
            create: function(uiActions, options) {
                return new GlideUIActions(uiActions, options);
            },
            executeUIAction: executeUIAction
        };
    
        function GlideUIActions(uiActions, options) {
            if (!uiActions) {
                throw 'uiActions must be provided';
            }
            var _uiActionsById = {};
            var _uiActions = [];
            options = options || {};
            uiActions.forEach(function(uiAction) {
                var action = new GlideUIAction(
                    uiAction.action_name,
                    uiAction.sys_id,
                    uiAction.name,
                    uiAction.disabled,
                    uiAction.display_types,
                    uiAction.navigate_back === true ? 'back' : 'default',
                    options.uiActionNotifier
                );
                _uiActionsById[action.getSysId()] = action;
                _uiActions.push(action);
            });
            this.getActions = function() {
                return _uiActions;
            };
            this.getAction = function(sysId) {
                return _uiActionsById[sysId];
            };
            this.getActionByName = function(name) {
                var foundAction;
                _uiActions.forEach(function(action) {
                    if (foundAction) {
                        return;
                    }
                    if (name === action.getName()) {
                        foundAction = action;
                    }
                });
                return foundAction;
            };
        }
    
        function GlideUIAction(name, sysId, displayName, disabled, displayTypes, navigateBehavior, uiActionNotifier) {
            var _inProgress = false;
            var _name = name;
            var _sysId = sysId;
            var _displayName = displayName;
            var _disabled = !!disabled;
            var _navigateBehavior;
            var _notifier = uiActionNotifier;
            switch (navigateBehavior) {
                case 'back':
                    _navigateBehavior = 'back';
                    break;
                default:
                    _navigateBehavior = 'default';
                    break;
            }
            var _displayTypes = {};
            if (displayTypes) {
                displayTypes.forEach(function(type) {
                    _displayTypes[type] = true;
                });
            }
            this.getSysId = function() {
                return _sysId;
            };
            this.getName = function() {
                return _name;
            };
            this.getDisplayName = function() {
                return _displayName;
            };
            this.getNavigateBehavior = function() {
                return _navigateBehavior;
            };
            this.isDisabled = function() {
                return _disabled;
            };
            this.isMoreMenuItem = function() {
                return !_displayTypes[ACTION_DISPLAY_TYPES.FORM_BUTTON] && _displayTypes[ACTION_DISPLAY_TYPES.FORM_MORE_ITEM];
            };
            this.execute = function(g_form) {
                if (this.isDisabled() || _inProgress) {
                    return false;
                }
                _inProgress = true;
                var $execute = executeUIAction(
                    ACTION_TYPES.FORM,
                    this.getSysId(),
                    g_form.getTableName(),
                    g_form.getSysId(),
                    g_form.isNewRecord() ? ACTION_OPERATIONS.INSERT : ACTION_OPERATIONS.UPDATE,
                    g_form.serialize(true),
                    g_form.getEncodedRecord()
                ).finally(function() {
                    _inProgress = false;
                });
                _notifier(this.getName(), $execute);
                return $execute;
            };
        }
    
        function executeUIAction(actionType, actionSysId, tableName, recordSysId, operation, fields, encodedRecord) {
            var queryParams = {
                method: 'execute',
                type: actionType,
                operation: angular.isDefined(operation) ? operation : ACTION_OPERATIONS.UPDATE,
                action_id: actionSysId,
                table: tableName,
                sys_id: recordSysId,
                save_parms: JSON.stringify({})
            };
            var url = urlTools.getURL('ui_action', queryParams);
            return $http.post(url, {
                fields: fields || [],
                encoded_record: encodedRecord
            }).then(function(response) {
                var data = response.data;
                return {
                    sys_id: data.sys_id,
                    redirect: data.redirect
                };
            }).catch(function(data, status) {
                $log.log("Error executing uiAction: " + status);
            });
        }
    });;;
    /*! RESOURCE: /scripts/snm/auth/data/js_includes_data.js */
    /*! RESOURCE: /scripts/snm/auth/data/snm.auth.data.module.js */
    angular.module('snm.auth.data', []);;
    /*! RESOURCE: /scripts/snm/auth/data/glideUserSession.js */
    angular.module('snm.auth.data').provider('glideUserSession', function glideUserSessionProvider() {
        'use strict';
        var _initialLoginState;
        var _initialUser;
        this.setUserSession = function(session) {
            if (!session) {
                return;
            }
            _initialLoginState = session.initialLoginState;
            if (session.initialLoginState && session.initialUser) {
                _initialUser = session.initialUser;
            }
        };
        this.$get = function glideUserSession($rootScope, $q, $http, $log, urlTools, glideUserFactory, $window, glideSystemProperties, xmlUtil) {
            var $currentUser;
            var _currentLoginState = false;
            var _currentUser;
            $rootScope.$on('@page.login', function() {
                _currentLoginState = false;
                _initialLoginState = false;
                $currentUser = null;
            });
    
            function loadCurrentUser() {
                if (!$currentUser) {
                    $currentUser = $q.defer();
                    if (_initialLoginState && _initialUser) {
                        _currentUser = glideUserFactory.create(_initialUser);
                        $currentUser.resolve(_currentUser);
                        return $currentUser.promise;
                    }
                    var src = urlTools.getURL('get_user');
                    $http.get(src).then(function(response) {
                        _currentUser = glideUserFactory.create(response.data);
                        $currentUser.resolve(_currentUser);
                    }, function() {
                        if ($currentUser)
                            $currentUser.reject();
                        $currentUser = null;
                    });
                }
                return $currentUser.promise;
            }
    
            function isLoggedIn() {
                return _initialLoginState || _currentLoginState;
            }
    
            function isExternalAuthEnabled() {
                return glideSystemProperties.get('glide.authenticate.multisso.enabled');
            }
    
            function getIdpRedirectUrl(ssoId) {
                var ssoRedirectUri;
                if (isExternalAuthEnabled()) {
                    var redirectSysId = glideSystemProperties.get('glide.authenticate.sso.redirect.idp') || ssoId;
                    if (redirectSysId && redirectSysId.length > 0) {
                        ssoRedirectUri = '/login_with_sso.do?glide_sso_id=' + redirectSysId;
                    }
                }
                return ssoRedirectUri;
            }
    
            function logout() {
                $window.location.href = '/logout.do';
                var $d = $q.defer();
                return $d.promise;
            }
    
            function login(username, password, rememberMe) {
                _initialLoginState = false;
                var params = {
                    'sysparm_type': 'login',
                    'ni.nolog.user_password': true,
                    'remember_me': !!rememberMe,
                    'user_name': username,
                    'user_password': password
                };
                return _sendLoginRequest(params).then(function(response) {
                    if (!response.data) {
                        $log.warn('login server failure:', response);
                        return $q.reject('unknown_error');
                    }
                    var status;
                    switch (response.data.status) {
                        default:
                            case 'error':
                            _currentLoginState = false;
                        status = $q.reject('invalid_username_or_password');
                        break;
                        case 'success':
                                _currentLoginState = true;
                            status = $q.resolve(response.data.status);
                            break;
                        case 'mfa_code_required':
                                _currentLoginState = false;
                            status = $q.resolve(response.data.status);
                            break;
                    }
                    return status;
                }, function(response) {
                    $log.warn('login server failure:', response);
                    _currentLoginState = false;
                    return $q.reject('unknown_error');
                });
            }
    
            function requestMfaCode() {
                return _sendLoginRequest({
                    send_mfa_code: true
                }).then(function(response) {
                    var status;
                    if (!response.data) {
                        status = $q.reject('unknown_error');
                    } else if (response.data.status === 'send_mfa_code_success') {
                        status = $q.resolve('success');
                    } else {
                        status = $q.reject('send_mfa_code_failure');
                    }
                    return status;
                }, function(response) {
                    $log.warn('mfa code delivery error:', response);
                    return $q.reject('unknown_error');
                });
            }
    
            function validateMfaCode(mfaCode) {
                var params = {
                    'sysparm_type': 'login',
                    'validate_mfa_code': true,
                    'mfa_code': mfaCode
                };
                return _sendLoginRequest(params).then(function(response) {
                    var status;
                    if (!response.data) {
                        _currentLoginState = false;
                        status = $q.reject('unknown_error');
                    } else {
                        _currentLoginState = response.data.status === 'success';
                        status = _currentLoginState ? $q.resolve('success') : $q.reject('invalid_mfa_code');
                    }
                    return status;
                }, function(response) {
                    $log.warn('mfa validation server error:', response);
                    return $q.reject('unknown_error');
                });
            }
    
            function _sendLoginRequest(params) {
                return $http({
                    method: 'POST',
                    url: urlTools.getURL('view_form.login'),
                    data: urlTools.encodeURIParameters(params),
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    }
                });
            }
    
            function getSsoRedirectUrlForUsername(username) {
                var $d = $q.defer();
                $http({
                    method: 'POST',
                    url: '/xmlhttp.do',
                    data: urlTools.encodeURIParameters({
                        sysparm_processor: 'MultiSSO_ClientHelper',
                        sysparm_scope: 'global',
                        sysparm_name: 'ssoByUser',
                        sysparm_user_id: username
                    }),
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    },
                    transformResponse: function(response) {
                        return xmlUtil.getDataFromXml(response, 'result');
                    }
                }).then(function(response) {
                        var data = response.data[0];
                        var url;
                        if (data) {
                            if (data.glide_sso_id) {
                                url = getIdpRedirectUrl(data.glide_sso_id);
                            } else {
                                url = data.discovery_service_url;
                            }
                            $d.resolve(url);
                        } else {
                            $d.reject('No external identity provider found for the username: ' + username);
                        }
                    },
                    function(err) {
                        $d.reject(err);
                    });
                return $d.promise;
            }
            return {
                loadCurrentUser: loadCurrentUser,
                isLoggedIn: isLoggedIn,
                logout: logout,
                login: login,
                requestMfaCode: requestMfaCode,
                validateMfaCode: validateMfaCode,
                isExternalAuthEnabled: isExternalAuthEnabled,
                getIdpRedirectUrl: getIdpRedirectUrl,
                getSsoRedirectUrlForUsername: getSsoRedirectUrlForUsername
            };
        };
    }).config(function(glideUserSessionProvider) {
        glideUserSessionProvider.setUserSession(window['SNM_USER_SESSION']);
    });;;
    /*! RESOURCE: /scripts/sn/common/clientScript/js_includes_clientScript.js */
    /*! RESOURCE: /scripts/sn/common/clientScript/dist/clientScript_components.js */
    ! function(b, a) {
        "function" == typeof define && define.amd ? define([], a) : b.amdWeb = a()
    }(this, function() {
        "function" != typeof Array.prototype.indexOf && (Array.prototype.indexOf = function(d, a) {
            var b, c = this.length;
            if (!c) return -1;
            if (a = Number(a), ("number" != typeof a || isNaN(a)) && (a = 0), a >= c) return -1;
            for (0 > a && (a = c - Math.abs(a)), b = a; c > b; b++)
                if (this[b] === d) return b;
            return -1
        }), "function" != typeof Function.prototype.bind && (Function.prototype.bind = function(a) {
            var b, d, c, e;
            if ("function" != typeof this) throw new TypeError("Target is not callable, and unable to be bound");
            return b = Array.prototype.slice, d = b.call(arguments, 1), c = this, "undefined" == typeof a && (a = c), e = function() {
                var e = b.call(arguments, 0);
                return c.apply(a, d.concat(e))
            }
        })
    });
    (function() {
        "use strict";
    
        function $$utils$$objectOrFunction(x) {
            return typeof x === 'function' || (typeof x === 'object' && x !== null);
        }
    
        function $$utils$$isFunction(x) {
            return typeof x === 'function';
        }
    
        function $$utils$$isMaybeThenable(x) {
            return typeof x === 'object' && x !== null;
        }
        var $$utils$$_isArray;
        if (!Array.isArray) {
            $$utils$$_isArray = function(x) {
                return Object.prototype.toString.call(x) === '[object Array]';
            };
        } else {
            $$utils$$_isArray = Array.isArray;
        }
        var $$utils$$isArray = $$utils$$_isArray;
        var $$utils$$now = Date.now || function() {
            return new Date().getTime();
        };
    
        function $$utils$$F() {}
        var $$utils$$o_create = (Object.create || function(o) {
            if (arguments.length > 1) {
                throw new Error('Second argument not supported');
            }
            if (typeof o !== 'object') {
                throw new TypeError('Argument must be an object');
            }
            $$utils$$F.prototype = o;
            return new $$utils$$F();
        });
        var $$asap$$len = 0;
        var $$asap$$default = function asap(callback, arg) {
            $$asap$$queue[$$asap$$len] = callback;
            $$asap$$queue[$$asap$$len + 1] = arg;
            $$asap$$len += 2;
            if ($$asap$$len === 2) {
                $$asap$$scheduleFlush();
            }
        };
        var $$asap$$browserGlobal = (typeof window !== 'undefined') ? window : {};
        var $$asap$$BrowserMutationObserver = $$asap$$browserGlobal.MutationObserver || $$asap$$browserGlobal.WebKitMutationObserver;
        var $$asap$$isWorker = typeof Uint8ClampedArray !== 'undefined' &&
            typeof importScripts !== 'undefined' &&
            typeof MessageChannel !== 'undefined';
    
        function $$asap$$useNextTick() {
            return function() {
                process.nextTick($$asap$$flush);
            };
        }
    
        function $$asap$$useMutationObserver() {
            var iterations = 0;
            var observer = new $$asap$$BrowserMutationObserver($$asap$$flush);
            var node = document.createTextNode('');
            observer.observe(node, {
                characterData: true
            });
            return function() {
                node.data = (iterations = ++iterations % 2);
            };
        }
    
        function $$asap$$useMessageChannel() {
            var channel = new MessageChannel();
            channel.port1.onmessage = $$asap$$flush;
            return function() {
                channel.port2.postMessage(0);
            };
        }
    
        function $$asap$$useSetTimeout() {
            return function() {
                setTimeout($$asap$$flush, 1);
            };
        }
        var $$asap$$queue = new Array(1000);
    
        function $$asap$$flush() {
            for (var i = 0; i < $$asap$$len; i += 2) {
                var callback = $$asap$$queue[i];
                var arg = $$asap$$queue[i + 1];
                callback(arg);
                $$asap$$queue[i] = undefined;
                $$asap$$queue[i + 1] = undefined;
            }
            $$asap$$len = 0;
        }
        var $$asap$$scheduleFlush;
        if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
            $$asap$$scheduleFlush = $$asap$$useNextTick();
        } else if ($$asap$$BrowserMutationObserver) {
            $$asap$$scheduleFlush = $$asap$$useMutationObserver();
        } else if ($$asap$$isWorker) {
            $$asap$$scheduleFlush = $$asap$$useMessageChannel();
        } else {
            $$asap$$scheduleFlush = $$asap$$useSetTimeout();
        }
    
        function $$$internal$$noop() {}
        var $$$internal$$PENDING = void 0;
        var $$$internal$$FULFILLED = 1;
        var $$$internal$$REJECTED = 2;
        var $$$internal$$GET_THEN_ERROR = new $$$internal$$ErrorObject();
    
        function $$$internal$$selfFullfillment() {
            return new TypeError("You cannot resolve a promise with itself");
        }
    
        function $$$internal$$cannotReturnOwn() {
            return new TypeError('A promises callback cannot return that same promise.')
        }
    
        function $$$internal$$getThen(promise) {
            try {
                return promise.then;
            } catch (error) {
                $$$internal$$GET_THEN_ERROR.error = error;
                return $$$internal$$GET_THEN_ERROR;
            }
        }
    
        function $$$internal$$tryThen(then, value, fulfillmentHandler, rejectionHandler) {
            try {
                then.call(value, fulfillmentHandler, rejectionHandler);
            } catch (e) {
                return e;
            }
        }
    
        function $$$internal$$handleForeignThenable(promise, thenable, then) {
            $$asap$$default(function(promise) {
                var sealed = false;
                var error = $$$internal$$tryThen(then, thenable, function(value) {
                    if (sealed) {
                        return;
                    }
                    sealed = true;
                    if (thenable !== value) {
                        $$$internal$$resolve(promise, value);
                    } else {
                        $$$internal$$fulfill(promise, value);
                    }
                }, function(reason) {
                    if (sealed) {
                        return;
                    }
                    sealed = true;
                    $$$internal$$reject(promise, reason);
                }, 'Settle: ' + (promise._label || ' unknown promise'));
                if (!sealed && error) {
                    sealed = true;
                    $$$internal$$reject(promise, error);
                }
            }, promise);
        }
    
        function $$$internal$$handleOwnThenable(promise, thenable) {
            if (thenable._state === $$$internal$$FULFILLED) {
                $$$internal$$fulfill(promise, thenable._result);
            } else if (promise._state === $$$internal$$REJECTED) {
                $$$internal$$reject(promise, thenable._result);
            } else {
                $$$internal$$subscribe(thenable, undefined, function(value) {
                    $$$internal$$resolve(promise, value);
                }, function(reason) {
                    $$$internal$$reject(promise, reason);
                });
            }
        }
    
        function $$$internal$$handleMaybeThenable(promise, maybeThenable) {
            if (maybeThenable.constructor === promise.constructor) {
                $$$internal$$handleOwnThenable(promise, maybeThenable);
            } else {
                var then = $$$internal$$getThen(maybeThenable);
                if (then === $$$internal$$GET_THEN_ERROR) {
                    $$$internal$$reject(promise, $$$internal$$GET_THEN_ERROR.error);
                } else if (then === undefined) {
                    $$$internal$$fulfill(promise, maybeThenable);
                } else if ($$utils$$isFunction(then)) {
                    $$$internal$$handleForeignThenable(promise, maybeThenable, then);
                } else {
                    $$$internal$$fulfill(promise, maybeThenable);
                }
            }
        }
    
        function $$$internal$$resolve(promise, value) {
            if (promise === value) {
                $$$internal$$reject(promise, $$$internal$$selfFullfillment());
            } else if ($$utils$$objectOrFunction(value)) {
                $$$internal$$handleMaybeThenable(promise, value);
            } else {
                $$$internal$$fulfill(promise, value);
            }
        }
    
        function $$$internal$$publishRejection(promise) {
            if (promise._onerror) {
                promise._onerror(promise._result);
            }
            $$$internal$$publish(promise);
        }
    
        function $$$internal$$fulfill(promise, value) {
            if (promise._state !== $$$internal$$PENDING) {
                return;
            }
            promise._result = value;
            promise._state = $$$internal$$FULFILLED;
            if (promise._subscribers.length === 0) {} else {
                $$asap$$default($$$internal$$publish, promise);
            }
        }
    
        function $$$internal$$reject(promise, reason) {
            if (promise._state !== $$$internal$$PENDING) {
                return;
            }
            promise._state = $$$internal$$REJECTED;
            promise._result = reason;
            $$asap$$default($$$internal$$publishRejection, promise);
        }
    
        function $$$internal$$subscribe(parent, child, onFulfillment, onRejection) {
            var subscribers = parent._subscribers;
            var length = subscribers.length;
            parent._onerror = null;
            subscribers[length] = child;
            subscribers[length + $$$internal$$FULFILLED] = onFulfillment;
            subscribers[length + $$$internal$$REJECTED] = onRejection;
            if (length === 0 && parent._state) {
                $$asap$$default($$$internal$$publish, parent);
            }
        }
    
        function $$$internal$$publish(promise) {
            var subscribers = promise._subscribers;
            var settled = promise._state;
            if (subscribers.length === 0) {
                return;
            }
            var child, callback, detail = promise._result;
            for (var i = 0; i < subscribers.length; i += 3) {
                child = subscribers[i];
                callback = subscribers[i + settled];
                if (child) {
                    $$$internal$$invokeCallback(settled, child, callback, detail);
                } else {
                    callback(detail);
                }
            }
            promise._subscribers.length = 0;
        }
    
        function $$$internal$$ErrorObject() {
            this.error = null;
        }
        var $$$internal$$TRY_CATCH_ERROR = new $$$internal$$ErrorObject();
    
        function $$$internal$$tryCatch(callback, detail) {
            try {
                return callback(detail);
            } catch (e) {
                $$$internal$$TRY_CATCH_ERROR.error = e;
                return $$$internal$$TRY_CATCH_ERROR;
            }
        }
    
        function $$$internal$$invokeCallback(settled, promise, callback, detail) {
            var hasCallback = $$utils$$isFunction(callback),
                value, error, succeeded, failed;
            if (hasCallback) {
                value = $$$internal$$tryCatch(callback, detail);
                if (value === $$$internal$$TRY_CATCH_ERROR) {
                    failed = true;
                    error = value.error;
                    value = null;
                } else {
                    succeeded = true;
                }
                if (promise === value) {
                    $$$internal$$reject(promise, $$$internal$$cannotReturnOwn());
                    return;
                }
            } else {
                value = detail;
                succeeded = true;
            }
            if (promise._state !== $$$internal$$PENDING) {} else if (hasCallback && succeeded) {
                $$$internal$$resolve(promise, value);
            } else if (failed) {
                $$$internal$$reject(promise, error);
            } else if (settled === $$$internal$$FULFILLED) {
                $$$internal$$fulfill(promise, value);
            } else if (settled === $$$internal$$REJECTED) {
                $$$internal$$reject(promise, value);
            }
        }
    
        function $$$internal$$initializePromise(promise, resolver) {
            try {
                resolver(function resolvePromise(value) {
                    $$$internal$$resolve(promise, value);
                }, function rejectPromise(reason) {
                    $$$internal$$reject(promise, reason);
                });
            } catch (e) {
                $$$internal$$reject(promise, e);
            }
        }
    
        function $$$enumerator$$makeSettledResult(state, position, value) {
            if (state === $$$internal$$FULFILLED) {
                return {
                    state: 'fulfilled',
                    value: value
                };
            } else {
                return {
                    state: 'rejected',
                    reason: value
                };
            }
        }
    
        function $$$enumerator$$Enumerator(Constructor, input, abortOnReject, label) {
            this._instanceConstructor = Constructor;
            this.promise = new Constructor($$$internal$$noop, label);
            this._abortOnReject = abortOnReject;
            if (this._validateInput(input)) {
                this._input = input;
                this.length = input.length;
                this._remaining = input.length;
                this._init();
                if (this.length === 0) {
                    $$$internal$$fulfill(this.promise, this._result);
                } else {
                    this.length = this.length || 0;
                    this._enumerate();
                    if (this._remaining === 0) {
                        $$$internal$$fulfill(this.promise, this._result);
                    }
                }
            } else {
                $$$internal$$reject(this.promise, this._validationError());
            }
        }
        $$$enumerator$$Enumerator.prototype._validateInput = function(input) {
            return $$utils$$isArray(input);
        };
        $$$enumerator$$Enumerator.prototype._validationError = function() {
            return new Error('Array Methods must be provided an Array');
        };
        $$$enumerator$$Enumerator.prototype._init = function() {
            this._result = new Array(this.length);
        };
        var $$$enumerator$$default = $$$enumerator$$Enumerator;
        $$$enumerator$$Enumerator.prototype._enumerate = function() {
            var length = this.length;
            var promise = this.promise;
            var input = this._input;
            for (var i = 0; promise._state === $$$internal$$PENDING && i < length; i++) {
                this._eachEntry(input[i], i);
            }
        };
        $$$enumerator$$Enumerator.prototype._eachEntry = function(entry, i) {
            var c = this._instanceConstructor;
            if ($$utils$$isMaybeThenable(entry)) {
                if (entry.constructor === c && entry._state !== $$$internal$$PENDING) {
                    entry._onerror = null;
                    this._settledAt(entry._state, i, entry._result);
                } else {
                    this._willSettleAt(c.resolve(entry), i);
                }
            } else {
                this._remaining--;
                this._result[i] = this._makeResult($$$internal$$FULFILLED, i, entry);
            }
        };
        $$$enumerator$$Enumerator.prototype._settledAt = function(state, i, value) {
            var promise = this.promise;
            if (promise._state === $$$internal$$PENDING) {
                this._remaining--;
                if (this._abortOnReject && state === $$$internal$$REJECTED) {
                    $$$internal$$reject(promise, value);
                } else {
                    this._result[i] = this._makeResult(state, i, value);
                }
            }
            if (this._remaining === 0) {
                $$$internal$$fulfill(promise, this._result);
            }
        };
        $$$enumerator$$Enumerator.prototype._makeResult = function(state, i, value) {
            return value;
        };
        $$$enumerator$$Enumerator.prototype._willSettleAt = function(promise, i) {
            var enumerator = this;
            $$$internal$$subscribe(promise, undefined, function(value) {
                enumerator._settledAt($$$internal$$FULFILLED, i, value);
            }, function(reason) {
                enumerator._settledAt($$$internal$$REJECTED, i, reason);
            });
        };
        var $$promise$all$$default = function all(entries, label) {
            return new $$$enumerator$$default(this, entries, true, label).promise;
        };
        var $$promise$race$$default = function race(entries, label) {
            var Constructor = this;
            var promise = new Constructor($$$internal$$noop, label);
            if (!$$utils$$isArray(entries)) {
                $$$internal$$reject(promise, new TypeError('You must pass an array to race.'));
                return promise;
            }
            var length = entries.length;
    
            function onFulfillment(value) {
                $$$internal$$resolve(promise, value);
            }
    
            function onRejection(reason) {
                $$$internal$$reject(promise, reason);
            }
            for (var i = 0; promise._state === $$$internal$$PENDING && i < length; i++) {
                $$$internal$$subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);
            }
            return promise;
        };
        var $$promise$resolve$$default = function resolve(object, label) {
            var Constructor = this;
            if (object && typeof object === 'object' && object.constructor === Constructor) {
                return object;
            }
            var promise = new Constructor($$$internal$$noop, label);
            $$$internal$$resolve(promise, object);
            return promise;
        };
        var $$promise$reject$$default = function reject(reason, label) {
            var Constructor = this;
            var promise = new Constructor($$$internal$$noop, label);
            $$$internal$$reject(promise, reason);
            return promise;
        };
        var $$es6$promise$promise$$counter = 0;
    
        function $$es6$promise$promise$$needsResolver() {
            throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
        }
    
        function $$es6$promise$promise$$needsNew() {
            throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
        }
        var $$es6$promise$promise$$default = $$es6$promise$promise$$Promise;
    
        function $$es6$promise$promise$$Promise(resolver) {
            this._id = $$es6$promise$promise$$counter++;
            this._state = undefined;
            this._result = undefined;
            this._subscribers = [];
            if ($$$internal$$noop !== resolver) {
                if (!$$utils$$isFunction(resolver)) {
                    $$es6$promise$promise$$needsResolver();
                }
                if (!(this instanceof $$es6$promise$promise$$Promise)) {
                    $$es6$promise$promise$$needsNew();
                }
                $$$internal$$initializePromise(this, resolver);
            }
        }
        $$es6$promise$promise$$Promise.all = $$promise$all$$default;
        $$es6$promise$promise$$Promise.race = $$promise$race$$default;
        $$es6$promise$promise$$Promise.resolve = $$promise$resolve$$default;
        $$es6$promise$promise$$Promise.reject = $$promise$reject$$default;
        $$es6$promise$promise$$Promise.prototype = {
            constructor: $$es6$promise$promise$$Promise,
            then: function(onFulfillment, onRejection) {
                var parent = this;
                var state = parent._state;
                if (state === $$$internal$$FULFILLED && !onFulfillment || state === $$$internal$$REJECTED && !onRejection) {
                    return this;
                }
                var child = new this.constructor($$$internal$$noop);
                var result = parent._result;
                if (state) {
                    var callback = arguments[state - 1];
                    $$asap$$default(function() {
                        $$$internal$$invokeCallback(state, child, callback, result);
                    });
                } else {
                    $$$internal$$subscribe(parent, child, onFulfillment, onRejection);
                }
                return child;
            },
            'catch': function(onRejection) {
                return this.then(null, onRejection);
            }
        };
        var $$es6$promise$polyfill$$default = function polyfill() {
            var local;
            if (typeof global !== 'undefined') {
                local = global;
            } else if (typeof window !== 'undefined' && window.document) {
                local = window;
            } else {
                local = self;
            }
            var es6PromiseSupport =
                "Promise" in local &&
                "resolve" in local.Promise &&
                "reject" in local.Promise &&
                "all" in local.Promise &&
                "race" in local.Promise &&
                (function() {
                    var resolve;
                    new local.Promise(function(r) {
                        resolve = r;
                    });
                    return $$utils$$isFunction(resolve);
                }());
            if (!es6PromiseSupport) {
                local.Promise = $$es6$promise$promise$$default;
            }
        };
        var es6$promise$umd$$ES6Promise = {
            'Promise': $$es6$promise$promise$$default,
            'polyfill': $$es6$promise$polyfill$$default
        };
        if (typeof define === 'function' && define['amd']) {
            define(function() {
                return es6$promise$umd$$ES6Promise;
            });
        } else if (typeof module !== 'undefined' && module['exports']) {
            module['exports'] = es6$promise$umd$$ES6Promise;
        } else if (typeof this !== 'undefined') {
            this['ES6Promise'] = es6$promise$umd$$ES6Promise;
        }
    }).call(this);
    (function() {
        'use strict';
        if (self.fetch) {
            return
        }
    
        function Headers(headers) {
            this.map = {}
            var self = this
            if (headers instanceof Headers) {
                headers.forEach(function(name, values) {
                    values.forEach(function(value) {
                        self.append(name, value)
                    })
                })
            } else if (headers) {
                Object.getOwnPropertyNames(headers).forEach(function(name) {
                    self.append(name, headers[name])
                })
            }
        }
        Headers.prototype.append = function(name, value) {
            name = name.toLowerCase()
            var list = this.map[name]
            if (!list) {
                list = []
                this.map[name] = list
            }
            list.push(value)
        }
        Headers.prototype['delete'] = function(name) {
            delete this.map[name.toLowerCase()]
        }
        Headers.prototype.get = function(name) {
            var values = this.map[name.toLowerCase()]
            return values ? values[0] : null
        }
        Headers.prototype.getAll = function(name) {
            return this.map[name.toLowerCase()] || []
        }
        Headers.prototype.has = function(name) {
            return this.map.hasOwnProperty(name.toLowerCase())
        }
        Headers.prototype.set = function(name, value) {
            this.map[name.toLowerCase()] = [value]
        }
        Headers.prototype.forEach = function(callback) {
            var self = this
            Object.getOwnPropertyNames(this.map).forEach(function(name) {
                callback(name, self.map[name])
            })
        }
    
        function consumed(body) {
            if (body.bodyUsed) {
                return Promise.reject(new TypeError('Already read'))
            }
            body.bodyUsed = true
        }
    
        function fileReaderReady(reader) {
            return new Promise(function(resolve, reject) {
                reader.onload = function() {
                    resolve(reader.result)
                }
                reader.onerror = function() {
                    reject(reader.error)
                }
            })
        }
    
        function readBlobAsArrayBuffer(blob) {
            var reader = new FileReader()
            reader.readAsArrayBuffer(blob)
            return fileReaderReady(reader)
        }
    
        function readBlobAsText(blob) {
            var reader = new FileReader()
            reader.readAsText(blob)
            return fileReaderReady(reader)
        }
        var support = {
            blob: 'FileReader' in self && 'Blob' in self && (function() {
                try {
                    new Blob();
                    return true
                } catch (e) {
                    return false
                }
            })(),
            formData: 'FormData' in self
        }
    
        function Body() {
            this.bodyUsed = false
            if (support.blob) {
                this._initBody = function(body) {
                    this._bodyInit = body
                    if (typeof body === 'string') {
                        this._bodyText = body
                    } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
                        this._bodyBlob = body
                    } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
                        this._bodyFormData = body
                    } else if (!body) {
                        this._bodyText = ''
                    } else {
                        throw new Error('unsupported BodyInit type')
                    }
                }
                this.blob = function() {
                    var rejected = consumed(this)
                    if (rejected) {
                        return rejected
                    }
                    if (this._bodyBlob) {
                        return Promise.resolve(this._bodyBlob)
                    } else if (this._bodyFormData) {
                        throw new Error('could not read FormData body as blob')
                    } else {
                        return Promise.resolve(new Blob([this._bodyText]))
                    }
                }
                this.arrayBuffer = function() {
                    return this.blob().then(readBlobAsArrayBuffer)
                }
                this.text = function() {
                    var rejected = consumed(this)
                    if (rejected) {
                        return rejected
                    }
                    if (this._bodyBlob) {
                        return readBlobAsText(this._bodyBlob)
                    } else if (this._bodyFormData) {
                        throw new Error('could not read FormData body as text')
                    } else {
                        return Promise.resolve(this._bodyText)
                    }
                }
            } else {
                this._initBody = function(body) {
                    this._bodyInit = body
                    if (typeof body === 'string') {
                        this._bodyText = body
                    } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
                        this._bodyFormData = body
                    } else if (!body) {
                        this._bodyText = ''
                    } else {
                        throw new Error('unsupported BodyInit type')
                    }
                }
                this.text = function() {
                    var rejected = consumed(this)
                    return rejected ? rejected : Promise.resolve(this._bodyText)
                }
            }
            if (support.formData) {
                this.formData = function() {
                    return this.text().then(decode)
                }
            }
            this.json = function() {
                return this.text().then(JSON.parse)
            }
            return this
        }
        var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']
    
        function normalizeMethod(method) {
            var upcased = method.toUpperCase()
            return (methods.indexOf(upcased) > -1) ? upcased : method
        }
    
        function Request(url, options) {
            options = options || {}
            this.url = url
            this.credentials = options.credentials || 'omit'
            this.headers = new Headers(options.headers)
            this.method = normalizeMethod(options.method || 'GET')
            this.mode = options.mode || null
            this.referrer = null
            if ((this.method === 'GET' || this.method === 'HEAD') && options.body) {
                throw new TypeError('Body not allowed for GET or HEAD requests')
            }
            this._initBody(options.body)
        }
    
        function decode(body) {
            var form = new FormData()
            body.trim().split('&').forEach(function(bytes) {
                if (bytes) {
                    var split = bytes.split('=')
                    var name = split.shift().replace(/\+/g, ' ')
                    var value = split.join('=').replace(/\+/g, ' ')
                    form.append(decodeURIComponent(name), decodeURIComponent(value))
                }
            })
            return form
        }
    
        function headers(xhr) {
            var head = new Headers()
            var pairs = xhr.getAllResponseHeaders().trim().split('\n')
            pairs.forEach(function(header) {
                var split = header.trim().split(':')
                var key = split.shift().trim()
                var value = split.join(':').trim()
                head.append(key, value)
            })
            return head
        }
        Request.prototype.fetch = function() {
            var self = this
            return new Promise(function(resolve, reject) {
                var xhr = new XMLHttpRequest()
                if (self.credentials === 'cors') {
                    xhr.withCredentials = true;
                }
    
                function responseURL() {
                    if ('responseURL' in xhr) {
                        return xhr.responseURL
                    }
                    if (/^X-Request-URL:/m.test(xhr.getAllResponseHeaders())) {
                        return xhr.getResponseHeader('X-Request-URL')
                    }
                    return;
                }
                xhr.onload = function() {
                    var status = (xhr.status === 1223) ? 204 : xhr.status
                    if (status < 100 || status > 599) {
                        reject(new TypeError('Network request failed'))
                        return
                    }
                    var options = {
                        status: status,
                        statusText: xhr.statusText,
                        headers: headers(xhr),
                        url: responseURL()
                    }
                    var body = 'response' in xhr ? xhr.response : xhr.responseText;
                    resolve(new Response(body, options))
                }
                xhr.onerror = function() {
                    reject(new TypeError('Network request failed'))
                }
                xhr.open(self.method, self.url, true)
                if ('responseType' in xhr && support.blob) {
                    xhr.responseType = 'blob'
                }
                self.headers.forEach(function(name, values) {
                    values.forEach(function(value) {
                        xhr.setRequestHeader(name, value)
                    })
                })
                xhr.send(typeof self._bodyInit === 'undefined' ? null : self._bodyInit)
            })
        }
        Body.call(Request.prototype)
    
        function Response(bodyInit, options) {
            if (!options) {
                options = {}
            }
            this._initBody(bodyInit)
            this.type = 'default'
            this.url = null
            this.status = options.status
            this.statusText = options.statusText
            this.headers = options.headers
            this.url = options.url || ''
        }
        Body.call(Response.prototype)
        self.Headers = Headers;
        self.Request = Request;
        self.Response = Response;
        self.fetch = function(url, options) {
            return new Request(url, options).fetch()
        }
        self.fetch.polyfill = true
    })();;
    /*! RESOURCE: /scripts/sn/common/clientScript/glideFormFieldFactory.js */
    (function(exports, undefined) {
        'use strict';
        var IS_INITIALIZED = 'isInitialized';
        exports.glideFormFieldFactory = {
            create: create,
            hasInputHelpers: hasInputHelpers,
            useDisplayValueForValue: useDisplayValueForValue,
            isMandatory: isMandatory,
            hasValue: hasValue,
            isInitialized: isInitialized,
            setInitialized: setInitialized
        };
    
        function create(field) {
            var attributes = field.attributes || {};
            return {
                isVisible: function() {
                    if (typeof field.fields !== 'undefined') {
                        var childVisibility = false;
                        field.fields.forEach(function(child) {
                            childVisibility |= !!child.visible;
                        });
                        if (!childVisibility) {
                            return false;
                        }
                    }
                    return field.visible === true;
                },
                isReadonly: function() {
                    return field.readonly === true || field.sys_readonly === true;
                },
                isMandatory: function() {
                    return isMandatory(field);
                },
                hasBarcodeHelper: function() {
                    return hasInputHelpers(field) && attributes.barcode === 'true';
                },
                hasCurrentLocationHelper: function() {
                    return hasInputHelpers(field) && attributes.current_location === 'true';
                },
                hasMessages: function() {
                    return field.messages && (field.messages.length > 0);
                }
            };
        }
    
        function isInitialized(field) {
            return field[IS_INITIALIZED] === true;
        }
    
        function setInitialized(field) {
            field[IS_INITIALIZED] = true;
        }
    
        function hasInputHelpers(field) {
            switch (field.type) {
                case 'boolean':
                case 'reference':
                    return false;
                default:
                    return true;
            }
        }
    
        function isMandatory(field) {
            switch (field.type) {
                case 'widget':
                    return false;
                default:
                    return !field.readonly && (field.mandatory === true || field.sys_mandatory === true);
            }
        }
    
        function hasValue(field) {
            if (field.type === "boolean")
                return true;
            var value = useDisplayValueForValue(field) ? field.displayValue : field.value;
            if (value == null) {
                return false;
            }
            if (typeof value === 'undefined') {
                return false;
            }
            var trimmed = String(value).trim();
            return trimmed.length > 0;
        }
    
        function useDisplayValueForValue(field) {
            switch (field.type) {
                case 'user_image':
                case 'glide_encrypted':
                case 'translated_text':
                    return true;
                default:
                    return false;
            }
        }
    })(window);;
    /*! RESOURCE: /scripts/sn/common/clientScript/glideFormFactory.js */
    (function(exports, document, glideFormFieldFactory, undefined) {
        'use strict';
        exports.glideFormFactory = {
            create: createGlideForm,
            glideRequest: exports.glideRequest
        };
        var DEFAULT_ACTION_NAME = 'none';
        var SUBMIT_ACTION_NAME = 'submit';
        var SAVE_ACTION_NAME = 'save';
        var EVENT_ON_CHANGE = 'onChange';
        var EVENT_CHANGE = 'change';
        var EVENT_ON_SUBMIT = 'onSubmit';
        var EVENT_SUBMIT = 'submit';
        var EVENT_ON_SUBMITTED = 'onSubmitted';
        var EVENT_SUBMITTED = 'submitted';
        var EVENT_ON_CHANGED = 'onChanged';
        var EVENT_CHANGED = 'changed';
        var EVENT_PROPERTY_CHANGE = 'propertyChange';
        var EVENT_ON_PROPERTY_CHANGE = 'onPropertyChange';
        var PROPERTY_CHANGE_FORM = 'FORM';
        var PROPERTY_CHANGE_FIELD = 'FIELD';
        var PROPERTY_CHANGE_SECTION = 'SECTION';
        var PROPERTY_CHANGE_RELATED_LIST = 'RELATED_LIST';
    
        function createGlideForm(tableName, sysId, fields, uiActions, options) {
            if (!fields) {
                fields = [];
            }
            var _sysId = sysId ? sysId : '-1';
            var _fields = fields;
            var _dirtyFields = _getDirtyQueryFields(fields);
            var _submitActionName = DEFAULT_ACTION_NAME;
            var _onSubmitHandlers = [];
            var _onSubmittedHandlers = [];
            var _onChangeHandlers = [];
            var _onChangedHandlers = [];
            var _onPropertyChangeHandlers = [];
            var _options = {
                getMappedField: null,
                getMappedFieldName: null,
                uiMessageHandler: null,
                encodedRecord: null,
                relatedLists: null,
                sections: null,
                document: null
            };
    
            function GlideForm() {
                this.hasField = function(fieldName) {
                    var field = _getField(fieldName);
                    return field !== null;
                };
                this.getFieldNames = function() {
                    var fieldNames = [];
                    _fields.forEach(function(field) {
                        fieldNames.push(field.name);
                    });
                    return fieldNames;
                };
                this.setLabel = function(fieldName, label) {
                    var field = _getField(fieldName);
                    if (!field) {
                        return;
                    }
                    field.label = label;
                    this.$private.events.propertyChange(
                        PROPERTY_CHANGE_FIELD,
                        fieldName,
                        'label'
                    );
                };
                this.setLabelOf = this.setLabel;
                this.getLabel = function(fieldName) {
                    var field = _getField(fieldName);
                    if (!field) {
                        return;
                    }
                    return field.label;
                };
                this.getLabelOf = this.getLabel;
                this.addDecoration = function(fieldName, icon, text) {
                    var field = _getField(fieldName);
                    if (!field) {
                        return;
                    }
                    if (!field.decorations || !_isArray(field.decorations)) {
                        field.decorations = [];
                    }
                    var deco = {
                        icon: icon,
                        text: text
                    };
                    for (var i = 0; i < field.decorations.length; i++) {
                        var dec = field.decorations[i];
                        if ((dec.icon === icon) && (dec.text === text)) {
                            return;
                        }
                    }
                    field.decorations.push(deco);
                    this.$private.events.propertyChange(
                        PROPERTY_CHANGE_FIELD,
                        field.name,
                        'decorations'
                    );
                };
                this.removeDecoration = function(fieldName, icon, text) {
                    var field = _getField(fieldName);
                    if (!field)
                        return;
                    if (!field.decorations || !_isArray(field.decorations)) {
                        return;
                    }
                    for (var i = 0; i < field.decorations.length; i++) {
                        var dec = field.decorations[i];
                        if ((dec.icon === icon) && (dec.text === text)) {
                            field.decorations.splice(i, 1);
                            return;
                        }
                    }
                    this.$private.events.propertyChange(
                        PROPERTY_CHANGE_FIELD,
                        field.name,
                        'decorations'
                    );
                };
                this.setFieldPlaceholder = function(fieldName, value) {
                    var field = _getField(fieldName);
                    if (!field) {
                        return;
                    }
                    field.placeholder = value;
                    this.$private.events.propertyChange(
                        PROPERTY_CHANGE_FIELD,
                        field.name,
                        'placeholder'
                    );
                };
                this.getEncodedRecord = function() {
                    return _options.encodedRecord || '';
                };
                this.isMandatory = function(fieldName) {
                    var field = _getField(fieldName);
                    return field ? !!field.mandatory : false;
                };
                this.setMandatory = function(fieldName, isMandatory) {
                    var field = _getField(fieldName);
                    if (!field)
                        return;
                    if (field.sys_mandatory) {
                        return;
                    }
                    isMandatory = _getBoolean(isMandatory);
                    field.mandatory = isMandatory;
                    this.$private.events.propertyChange(
                        PROPERTY_CHANGE_FIELD,
                        field.name,
                        'mandatory'
                    );
                };
                this.isReadOnly = function(fieldName) {
                    var field = _getField(fieldName);
                    return field ? !!field.readonly : false;
                };
                this.setReadOnly = function(fieldName, readonly) {
                    var field = _getField(fieldName);
                    if (!field) {
                        return;
                    }
                    if (field.sys_readonly) {
                        return;
                    }
                    field.readonly = _getBoolean(readonly);
                    this.$private.events.propertyChange(
                        PROPERTY_CHANGE_FIELD,
                        field.name,
                        'readonly'
                    );
                };
                this.setReadonly = this.setReadOnly;
                this.setDisabled = this.setReadOnly;
                this.isVisible = function(fieldName) {
                    var field = _getField(fieldName);
                    return field ? !!field.visible : false;
                };
                this.setVisible = function(fieldName, isVisible) {
                    var field = _getField(fieldName);
                    if (!field) {
                        return;
                    }
                    field.visible = _getBoolean(isVisible);
                    this.$private.events.propertyChange(
                        PROPERTY_CHANGE_FIELD,
                        field.name,
                        'visible'
                    );
                };
                this.setDisplay = this.setVisible;
                this.getValue = function(fieldName) {
                    var field = _getField(fieldName);
                    if (!field) {
                        return '';
                    }
                    return (typeof field.value !== 'undefined' && field.value !== null) ? field.value.toString() : '';
                };
                this.getDisplayValue = function(fieldName) {
                    var field = _getField(fieldName);
                    if (!field) {
                        return '';
                    }
                    return field.displayValue;
                };
                this.clearValue = function(fieldName) {
                    this.setValue(fieldName, '');
                };
                this.setValue = function(fieldName, value, displayValue) {
                    var field = _getField(fieldName);
                    _setValue(this, field, value, displayValue);
                };
                this.getTableName = function() {
                    return tableName;
                };
                this.isNewRecord = function() {
                    return _sysId === "-1";
                };
                this.getSysId = function() {
                    return _sysId;
                };
                this.getUniqueValue = this.getSysId;
                this.getBooleanValue = function(fieldName) {
                    var val = this.getValue(fieldName);
                    val = val ? val + '' : val;
                    if (!val || val.length === 0 || val == "false") {
                        return false;
                    }
                    return true;
                };
                this.getDecimalValue = function(fieldName) {
                    var value = this.getValue(fieldName);
                    if (!value || (value.length === 0)) {
                        return 0;
                    }
                    return parseFloat(value);
                };
                this.getIntValue = function(fieldName) {
                    var value = this.getValue(fieldName);
                    if (typeof value === 'string') {
                        value = value.trim();
                    }
                    if (!value || (value.length === 0)) {
                        return 0;
                    }
                    return parseInt(value, 10);
                };
                this.addOption = function(fieldName, choiceValue, choiceLabel, choiceIndex) {
                    var field = _getField(fieldName);
                    if (!field) {
                        return;
                    }
                    _addToOptionStack(field, 'add', choiceValue, choiceLabel, choiceIndex);
                    this.$private.events.propertyChange(
                        PROPERTY_CHANGE_FIELD,
                        field.name,
                        'optionStack'
                    );
                };
                this.clearOptions = function(fieldName) {
                    var field = _getField(fieldName);
                    if (!field) {
                        return;
                    }
                    _addToOptionStack(field, 'clear');
                    this.$private.events.propertyChange(
                        PROPERTY_CHANGE_FIELD,
                        field.name,
                        'optionStack'
                    );
                };
                this.removeOption = function(fieldName, choiceValue) {
                    var field = _getField(fieldName);
                    if (!field) {
                        return;
                    }
                    _addToOptionStack(field, 'remove', choiceValue);
                    this.$private.events.propertyChange(
                        PROPERTY_CHANGE_FIELD,
                        field.name,
                        'optionStack'
                    );
                };
                this.hideRelatedList = function(listTableName) {
                    var list = _getRelatedList(listTableName);
                    if (!list) {
                        return;
                    }
                    list.visible = false;
                    this.$private.events.propertyChange(
                        PROPERTY_CHANGE_RELATED_LIST,
                        listTableName,
                        'visible'
                    );
                };
                this.hideRelatedLists = function() {
                    if (!_options.relatedLists) {
                        return;
                    }
                    _options.relatedLists.forEach(function(list) {
                        this.hideRelatedList(_getRelatedListName(list));
                    }, this);
                };
                this.showRelatedList = function(listTableName) {
                    var list = _getRelatedList(listTableName);
                    if (!list) {
                        return;
                    }
                    list.visible = true;
                    this.$private.events.propertyChange(
                        PROPERTY_CHANGE_RELATED_LIST,
                        listTableName,
                        'visible'
                    );
                };
                this.showRelatedLists = function() {
                    if (!_options.relatedLists) {
                        return;
                    }
                    _options.relatedLists.forEach(function(list) {
                        this.showRelatedList(_getRelatedListName(list));
                    }, this);
                };
                this.getRelatedListNames = function() {
                    var listNames = [];
                    if (_options.relatedLists) {
                        _options.relatedLists.forEach(function(list) {
                            listNames.push(_getRelatedListName(list));
                        });
                    }
                    return listNames;
                };
                this.getSectionNames = function() {
                    var sectionNames = [];
                    if (_options.sections) {
                        _options.sections.forEach(function(section) {
                            var sectionName = _getSectionName(section);
                            if (sectionName !== null) {
                                sectionNames.push(sectionName);
                            }
                        });
                    }
                    return sectionNames;
                };
                this.setSectionDisplay = function(sectionName, display) {
                    var section = _getSection(sectionName);
                    if (!section) {
                        return;
                    }
                    section.visible = !!display;
                    this.$private.events.propertyChange(
                        PROPERTY_CHANGE_SECTION,
                        sectionName,
                        'visible'
                    );
                };
                this.getReference = function(fieldName, callback) {
                    if (!callback) {
                        _logWarn('GETREF:NOCB', 'Mobile scripts must specify a callback function');
                        return;
                    }
                    var field = _getField(fieldName);
                    if (!field) {
                        _logWarn('GETREF:FNF', 'Field not found: ' + fieldName);
                        return;
                    }
                    var table = _getReferenceTable(field);
                    var referenceKey = field.reference_key ? field.reference_key : 'sys_id';
                    var gr = new exports.GlideRecord(table);
                    gr.get(referenceKey, field.value, callback);
                };
                this.addErrorMessage = function(message) {
                    _fireUiMessage(this, 'errorMessage', message);
                };
                this.addInfoMessage = function(message) {
                    _fireUiMessage(this, 'infoMessage', message);
                };
                this.clearMessages = function() {
                    _fireUiMessage(this, 'clearMessages');
                };
                this.showFieldMsg = function(fieldName, message, type, scrollForm) {
                    var field = _getField(fieldName);
                    if (!field) {
                        return;
                    }
                    if (!field.messages) {
                        field.messages = [];
                    }
                    switch (type) {
                        default: return;
                        case 'info':
                                case 'error':
                                break;
                    }
                    field.messages.push({
                        message: message,
                        type: type
                    });
                    this.$private.events.propertyChange(
                        PROPERTY_CHANGE_FIELD,
                        fieldName,
                        'messages'
                    );
                };
                this.hideFieldMsg = function(fieldName, clearAll) {
                    var field = _getField(fieldName);
                    if (!field) {
                        return;
                    }
                    if (!field.messages || !_isArray(field.messages)) {
                        return;
                    }
                    if (clearAll) {
                        field.messages = [];
                    } else {
                        field.messages.shift();
                    }
                    this.$private.events.propertyChange(
                        PROPERTY_CHANGE_FIELD,
                        fieldName,
                        'messages'
                    );
                };
                this.hideAllFieldMsgs = function(type) {
                    switch (type) {
                        default: return;
                        case 'info':
                                case 'error':
                                break;
                    }
                    for (var i = 0; i < _fields.length; i++) {
                        var msgs = _fields[i].messages;
                        if (!msgs || !_isArray(msgs)) {
                            continue;
                        }
                        for (var j = 0; j < msgs.length; j++) {
                            if (msgs[j].type === type) {
                                msgs.splice(j, 1);
                            }
                        }
                    }
                    this.$private.events.propertyChange(
                        PROPERTY_CHANGE_FORM,
                        null,
                        'messages'
                    );
                };
                this.showErrorBox = function(fieldName, message, scrollForm) {
                    this.showFieldMsg(fieldName, message, 'error', scrollForm);
                };
                this.hideErrorBox = function(fieldName) {
                    this.hideFieldMsg(fieldName, false);
                };
                this.getActionName = function() {
                    return _submitActionName;
                };
                this.save = function() {
                    return this.submit(SAVE_ACTION_NAME);
                };
                this.submit = function(submitActionName) {
                    var formDocument = _options.document ? _options.document : document;
                    var activeElement = formDocument.activeElement;
                    if (activeElement) {
                        activeElement.blur();
                    }
                    _submitActionName = submitActionName || SUBMIT_ACTION_NAME;
                    if (!_hasMandatoryFields(this) || !_runSubmitScripts()) {
                        _submitActionName = DEFAULT_ACTION_NAME;
                        return false;
                    }
                    var uiAction = _getUIAction(submitActionName);
                    if (!uiAction)
                        return true;
                    return uiAction.execute(this);
                };
                this.serialize = function(onlyDirtyFields) {
                    var serializeField = function(field, fields) {
                        var fieldCopy = _copy(field);
                        if (fieldCopy.value == null || typeof fieldCopy.value === 'undefined') {
                            fieldCopy.value = '';
                        }
                        fields.push(fieldCopy);
                    };
                    var serializedFields = [];
                    if (onlyDirtyFields === true) {
                        Object.keys(_dirtyFields).forEach(function(fieldName) {
                            serializeField(_getField(fieldName), serializedFields);
                        });
                    } else {
                        _fields.forEach(function(field) {
                            serializeField(field, serializedFields);
                        });
                    }
                    return serializedFields;
                };
                this.$private = {
                    options: function(options) {
                        if (!options) {
                            return;
                        }
                        if (typeof options === 'string') {
                            return _options[options];
                        }
                        Object.keys(options).forEach(function(optionName) {
                            if (_options[optionName]) {
                                throw 'Cannot override option: ' + optionName;
                            }
                            _options[optionName] = options[optionName];
                        });
                    },
                    events: {
                        on: function(eventName, fn) {
                            switch (eventName) {
                                case EVENT_CHANGE:
                                case EVENT_ON_CHANGE:
                                    _onChangeHandlers.push(fn);
                                    break;
                                case EVENT_SUBMIT:
                                case EVENT_ON_SUBMIT:
                                    _onSubmitHandlers.push(fn);
                                    break;
                                case EVENT_SUBMITTED:
                                case EVENT_ON_SUBMITTED:
                                    _onSubmittedHandlers.push(fn);
                                    break;
                                case EVENT_CHANGED:
                                case EVENT_ON_CHANGED:
                                    _onChangedHandlers.push(fn);
                                    break;
                                case EVENT_PROPERTY_CHANGE:
                                case EVENT_ON_PROPERTY_CHANGE:
                                    _onPropertyChangeHandlers.push(fn);
                                    break;
                                default:
                                    throw 'Unsupported GlideForm event: ' + eventName;
                            }
                        },
                        propertyChange: function(type, name, propertyName) {
                            if (_onPropertyChangeHandlers.length == 0) {
                                return;
                            }
                            switch (type) {
                                default: type = PROPERTY_CHANGE_FIELD;
                                case PROPERTY_CHANGE_FIELD:
                                        case PROPERTY_CHANGE_SECTION:
                                        case PROPERTY_CHANGE_RELATED_LIST:
                                        break;
                            }
                            _onPropertyChangeHandlers.forEach(function(fn) {
                                fn.call(
                                    fn,
                                    type,
                                    name,
                                    propertyName
                                );
                            });
                        },
                        off: function(eventName) {
                            switch (eventName) {
                                case EVENT_CHANGE:
                                case EVENT_ON_CHANGE:
                                    _onChangeHandlers = [];
                                    break;
                                case EVENT_SUBMIT:
                                case EVENT_ON_SUBMIT:
                                    _onSubmitHandlers = [];
                                    break;
                                case EVENT_SUBMITTED:
                                case EVENT_ON_SUBMITTED:
                                    _onSubmittedHandlers = [];
                                    break;
                                case EVENT_CHANGED:
                                case EVENT_ON_CHANGED:
                                    _onChangedHandlers = [];
                                    break;
                                case EVENT_PROPERTY_CHANGE:
                                case EVENT_ON_PROPERTY_CHANGE:
                                    _onPropertyChangeHandlers = [];
                                    break;
                                default:
                                    throw 'Unsupported GlideForm event: ' + eventName;
                            }
                        },
                        cleanup: function() {
                            _onChangeHandlers = [];
                            _onSubmitHandlers = [];
                            _onSubmittedHandlers = [];
                            _onChangedHandlers = [];
                            _onPropertyChangeHandlers = [];
                        }
                    }
                };
            }
            var _valueCalls = 0;
    
            function _setValue(g_form, field, value, displayValue, skipDerivedFieldUpdate, skipDisplayValueUpdate) {
                if (!field) {
                    return;
                }
                var oldValue = field.value;
                if (oldValue !== value) {
                    _dirtyFields[field.name] = true;
                }
                field.value = value;
                if (field.type === 'reference') {
                    if (!skipDerivedFieldUpdate) {
                        _updateDerivedFields(g_form, field);
                    }
                    if (!skipDisplayValueUpdate && glideFormFieldFactory.hasValue(field) && !displayValue) {
                        field.displayValue = '';
                        g_form.getReference(field.name, function(gr) {
                            var displayValue = gr.getDisplayValue();
                            field.value = oldValue;
                            _setValue(g_form, field, value, displayValue, true, true);
                        });
                        return;
                    }
                }
                field.displayValue = typeof displayValue !== 'undefined' && displayValue != null ? displayValue : value;
                var fields = _getDependentFields(field.name);
                fields.forEach(function(field) {
                    if (field.dependentValue !== value) {
                        field.dependentValue = value;
                    }
                    if (field.ed && field.ed.dependent_value !== value)
                        field.ed.dependent_value = value;
                });
                _fireValueChange(field, oldValue, value);
            }
    
            function _getRelatedList(listTableName) {
                if (!_options.relatedLists) {
                    return null;
                }
                var foundList = null;
                _options.relatedLists.forEach(function(list) {
                    if (foundList) {
                        return;
                    }
                    if (listTableName === _getRelatedListName(list)) {
                        foundList = list;
                        return;
                    }
                    if (listTableName === list.table || listTableName === list.field) {
                        foundList = list;
                        return;
                    }
                });
                return foundList;
            }
    
            function _getRelatedListName(list) {
                return list.table + '.' + list.field;
            }
    
            function _getSection(sectionName) {
                if (!_options.sections) {
                    return null;
                }
                var foundSection = null;
                _options.sections.forEach(function(section) {
                    if (foundSection) {
                        return;
                    }
                    var name = _getSectionName(section);
                    if (name === sectionName) {
                        foundSection = section;
                        return;
                    }
                });
                return foundSection;
            }
    
            function _getSectionName(section) {
                var sectionName = section.caption;
                if (!sectionName) {
                    return null;
                }
                return sectionName.toLowerCase().replace(" ", "_").replace(/[^0-9a-z_]/gi, "");
            }
    
            function _fireValueChange(field, oldValue, value) {
                if (_onChangeHandlers.length > 0) {
                    _valueCalls++;
                    _onChangeHandlers.forEach(function(fn) {
                        fn.call(fn, field.name, oldValue, value);
                    });
                    _valueCalls--;
                }
                if (_options.getMappedFieldName) {
                    var mappedName = _options.getMappedFieldName(field.name);
                    _valueCalls++;
                    _onChangeHandlers.forEach(function(fn) {
                        fn.call(fn, mappedName, oldValue, value);
                    });
                    _valueCalls--;
                }
                if ((_valueCalls == 0) && _onChangedHandlers.length > 0) {
                    _onChangedHandlers.forEach(function(fn) {
                        fn.call(fn);
                    });
                }
            }
    
            function _updateDerivedFields(g_form, originatingField) {
                var derivedFields = _getDerivedFields(originatingField.name);
                if (!glideFormFieldFactory.hasValue(originatingField)) {
                    derivedFields.forEach(function(field) {
                        _setValue(g_form, field, '', null, true);
                    });
                    return;
                }
                var relativeFieldNames = [];
                var fieldsByRelativeFieldName = {};
                derivedFields.forEach(function(field) {
                    var relativeField = _relativeDerivedFieldName(field.name, originatingField.name);
                    fieldsByRelativeFieldName[relativeField] = field;
                    relativeFieldNames.push(relativeField);
                });
                if (relativeFieldNames.length == 0) {
                    return;
                }
                var glideRequest = glideFormFactory.glideRequest;
                var referenceTable = _getReferenceTable(originatingField);
                var referenceKey = originatingField.reference_key ? originatingField.reference_key : 'sys_id';
                var requestUri = '/api/now/v1/table/' + referenceTable;
                var requestParams = {
                    sysparm_display_value: 'all',
                    sysparm_fields: relativeFieldNames.join(','),
                    sysparm_query: referenceKey + '=' + originatingField.value,
                    sysparm_limit: 1
                };
                glideRequest.get(requestUri, {
                    params: requestParams
                }).then(function(response) {
                    var result = response && response.data ? response.data.result : null;
                    if (result.length > 0) {
                        result = result[0];
                        var keys = Object.keys(result);
                        keys.forEach(function(fieldName) {
                            var field = fieldsByRelativeFieldName[fieldName];
                            var newFieldValues = result[fieldName];
                            _setValue(g_form, field, newFieldValues.value, newFieldValues.display_value, true);
                        });
                    }
                });
            }
    
            function _getField(fieldName) {
                for (var i = 0, iM = _fields.length; i < iM; i++) {
                    var field = _fields[i];
                    if (field.variable_name === fieldName || field.name === fieldName) {
                        return field;
                    }
                }
                if (_options.getMappedField) {
                    var mapped = _options.getMappedField(fieldName);
                    if (mapped) {
                        return mapped;
                    }
                }
                return null;
            }
    
            function _getDependentFields(fieldName) {
                var fields = [];
                for (var i = 0, iM = _fields.length; i < iM; i++) {
                    var field = _fields[i];
                    if (field.dependentField === fieldName) {
                        fields.push(field);
                    }
                }
                return fields;
            }
    
            function _getDerivedFields(fieldName) {
                var fields = [];
                var derivedFieldPrefix = fieldName + '.';
                for (var i = 0, iM = _fields.length; i < iM; i++) {
                    var field = _fields[i];
                    if (field.name.startsWith(derivedFieldPrefix)) {
                        fields.push(field);
                    }
                }
                return fields;
            }
    
            function _relativeDerivedFieldName(derivedFieldName, rootFieldName) {
                var prefix = rootFieldName + '.';
                return derivedFieldName.replace(prefix, '');
            }
    
            function _addToOptionStack(field, operation, value, label, index) {
                if (!field.optionStack) {
                    field.optionStack = [];
                }
                if (operation === 'add') {
                    var foundOperations = [];
                    for (var i = 0, iM = field.optionStack.length; i < iM; i++) {
                        if (field.optionStack[i].value === value) {
                            foundOperations.push(field.optionStack[i]);
                        }
                    }
                    if (foundOperations.length > 0) {
                        var isInChoiceList = false;
                        for (var i = 0, iM = foundOperations.length; i < iM; i++) {
                            switch (foundOperations[i].operation) {
                                case 'add':
                                    isInChoiceList = true;
                                    break;
                                case 'clear':
                                case 'remove':
                                    isInChoiceList = false;
                                    break;
                            }
                        }
                        if (isInChoiceList) {
                            return false;
                        }
                    }
                }
                var optionOper = {
                    operation: operation,
                    label: label,
                    value: value,
                    index: index
                };
                if (operation === 'clear') {
                    field.optionStack.splice(0, field.optionStack.length, optionOper);
                } else {
                    field.optionStack.push(optionOper);
                }
                return true;
            }
    
            function _hasMandatoryFields(g_form) {
                var emptyMandatoryFields = [];
                for (var i = 0; i < _fields.length; i++) {
                    var f = _fields[i];
                    if (!glideFormFieldFactory.isMandatory(f)) {
                        continue;
                    }
                    if (!glideFormFieldFactory.hasValue(f)) {
                        emptyMandatoryFields.push(f.label);
                    }
                }
                if (emptyMandatoryFields.length === 0) {
                    return true;
                }
                var message = "The following fields are incomplete:\n\n" + emptyMandatoryFields.join("\n");
                _fireUiMessage(g_form, 'mandatoryMessage', message);
                return false;
            }
    
            function _runSubmitScripts() {
                if (_onSubmitHandlers.length > 0) {
                    var result;
                    for (var i = 0, iM = _onSubmitHandlers.length; i < iM; i++) {
                        result = _onSubmitHandlers[i].call(null);
                        if (result === false) {
                            return false;
                        }
                    }
                }
                if (_onSubmittedHandlers.length > 0) {
                    _onSubmittedHandlers.forEach(function(fn) {
                        fn.call(fn, _submitActionName);
                    });
                }
                return true;
            }
    
            function _getUIAction(name) {
                if (!uiActions) {
                    return false;
                }
                return uiActions.getActionByName(name);
            }
    
            function _getDirtyQueryFields(fields) {
                var dirtyFields = {};
                fields.forEach(function(field) {
                    if (typeof field.dirtyQueryField !== 'undefined' && field.dirtyQueryField === true) {
                        dirtyFields[field.name] = true;
                    }
                });
                return dirtyFields;
            }
    
            function _getReferenceTable(field) {
                var referenceTable = field.ed ? field.ed.reference : undefined;
                if (typeof referenceTable === 'undefined') {
                    referenceTable = field.refTable;
                }
                if (typeof referenceTable === 'undefined') {
                    referenceTable = field.ref_table;
                }
                return referenceTable;
            }
    
            function _fireUiMessage(g_form, type, message) {
                var handledMessage = false;
                if (_options.uiMessageHandler) {
                    var response = _options.uiMessageHandler(g_form, type, message);
                    handledMessage = response !== false;
                }
                if (!handledMessage && typeof message !== 'undefined') {
                    alert(message);
                }
                g_form.$private.events.propertyChange(
                    PROPERTY_CHANGE_FORM,
                    null,
                    type
                );
            }
            var instance = new GlideForm();
            if (options) {
                instance.$private.options(options);
            }
            _deprecate(instance, [
                'disableAttachments',
                'enableAttachments',
                'flash',
                'getControl',
                'getElement',
                'getFormElement',
                'getSections'
            ]);
            return instance;
        }
    
        function _getBoolean(value) {
            if (value === 'true') {
                value = true;
            } else if (value === 'false') {
                value = false;
            }
            return value ? true : false;
        }
    
        function _notImplemented(instance, methods) {
            methods.forEach(function(method) {
                if (!instance[method]) {
                    instance[method] = function() {
                        _logWarn('UNSUPPORTED', 'Method ' + method + ' is not supported on mobile');
                    };
                }
            });
        }
    
        function _deprecate(instance, methods) {
            methods.forEach(function(method) {
                if (!instance[method]) {
                    instance[method] = function() {
                        _logWarn('DEPRECATED', 'Method ' + method + ' is deprecated and unsupported on mobile');
                    };
                }
            });
        }
    
        function _logWarn(code, msg) {
            if (console && console.warn) {
                console.warn('(g_form) [' + code + '] ' + msg);
            }
        }
    
        function _isArray(o) {
            if (!Array.isArray) {
                return Object.prototype.toString.call(arg) === '[object Array]';
            }
            return Array.isArray(o);
        }
    
        function _copy(source) {
            var dest = {};
            for (var prop in source) {
                if (Object.prototype.hasOwnProperty.call(source, prop)) {
                    switch (typeof source[prop]) {
                        case 'function':
                            break;
                        default:
                            dest[prop] = source[prop];
                    }
                }
            }
            return dest;
        }
    })(window, window.document || {}, window.glideFormFieldFactory);;
    /*! RESOURCE: /scripts/sn/common/clientScript/uiPolicyTypes.js */
    (function(exports, undefined) {
        'use strict';
        var UI_POLICY_TYPES = {
            dateTypes: {
                glide_date_time: "datetime",
                glide_date: "date",
                date: "date",
                datetime: "datetime",
                due_date: "datetime"
            },
            numberTypes: {
                decimal: "decimal",
                numeric: "numeric",
                integer: "integer",
                float: "float"
            },
            currencyTypes: {
                currency: "currency",
                price: "price"
            }
        };
        exports.UI_POLICY_TYPES = UI_POLICY_TYPES;
    })(window);;
    /*! RESOURCE: /scripts/sn/common/clientScript/uiPolicyFactory.js */
    (function(exports, undefined) {
        'use strict';
        exports.uiPolicyFactory = {
            create: createUiPolicy
        };
        var uiPolicyTypes = exports.UI_POLICY_TYPES;
    
        function createUiPolicy(g_form, uiPolicyMap, scripts) {
            var _tableName = uiPolicyMap.table;
            var _description = uiPolicyMap.short_description;
            var _onLoad = uiPolicyMap.onload;
            var _fields = uiPolicyMap.condition_fields;
            var _conditions = uiPolicyMap.conditions;
            var _watchFields = {};
            var _lastResult = null;
            var _isDebug = false;
            initializePolicy();
    
            function initializePolicy() {
                _fields.forEach(function(field, i) {
                    var condition = _conditions[i];
                    _watchFields[field] = true;
                    if (_isField2FieldComparisonlOper(condition.oper)) {
                        var field2 = condition.value.split('@')[0];
                        _watchFields[field2] = true;
                    }
                });
                g_form.$private.events.on('change', onChangeForm);
                if (_onLoad) {
                    runPolicy();
                }
            }
    
            function onChangeForm(fieldName, oldValue, newValue) {
                if (_watchFields[fieldName]) {
                    runPolicy();
                }
            }
    
            function runPolicy() {
                _debug("Running policy on table: " + _tableName + " " + _description);
                runActions(!!evaluateCondition());
            }
    
            function evaluateCondition() {
                _debug("--->>> Evaluating condition:");
                var result = "?";
                var conditionResult = true;
                var terms = _conditions;
                for (var i = 0; i < terms.length; i++) {
                    var t = terms[i];
                    if (t.newquery) {
                        if (result == "t") {
                            _debug("---<<< condition exited with: TRUE");
                            return true;
                        } else {
                            _debug(" OR (next condition)");
                            conditionResult = true;
                        }
                    }
                    if (!conditionResult)
                        continue;
                    if (t.or) {
                        if (result != "t")
                            result = _evaluateTermTF(t);
                    } else {
                        if ((result == "f") && (!t.newquery)) {
                            conditionResult = false;
                        } else {
                            result = _evaluateTermTF(t);
                        }
                    }
                }
                var response = result != "f";
                _debug("---<<< End evaluating condition with result: " + response);
                return response;
            }
    
            function _evaluateTermTF(term) {
                var result = evaluateTerm(term);
                _debugTerm(term, result);
                if (result)
                    return "t";
                else
                    return "f";
            }
    
            function evaluateTerm(term) {
                var type = term.type;
                if (uiPolicyTypes.dateTypes[type])
                    return evaluateTermDate(term);
                if (uiPolicyTypes.numberTypes[type] || uiPolicyTypes.currencyTypes[type])
                    return evaluateTermNumber(term);
                var field = term.field;
                if (!field)
                    return false;
                var oper = term.oper;
                var value = term.value;
                var userValue = g_form.getValue(field) + '';
                switch (oper) {
                    case '=':
                        return userValue === value;
                    case '!=':
                        return userValue != value;
                    case '<':
                        return userValue < value;
                    case '<=':
                        return userValue <= value;
                    case '>':
                        return userValue > value;
                    case '>=':
                        return userValue >= value;
                    case 'IN':
                        var values = value.split(',');
                        return userValue && (_inArray(userValue, values) !== -1);
                    case 'NOT IN':
                        var values2 = value.split(',');
                        return _inArray(userValue, values2) === -1;
                    case 'STARTSWITH':
                        if (type == 'reference')
                            userValue = g_form.getDisplayValue(field);
                        return userValue.indexOf(value) === 0;
                    case 'ENDSWITH':
                        if (type == 'reference')
                            userValue = g_form.getDisplayValue(field);
                        return userValue.lastIndexOf(value) == userValue.length - value.length;
                    case 'LIKE':
                        if (type == 'reference')
                            userValue = g_form.getDisplayValue(field);
                        return userValue.indexOf(value) != -1;
                    case 'NOT LIKE':
                        if (type == 'reference')
                            userValue = g_form.getDisplayValue(field);
                        return userValue.indexOf(value) == -1;
                    case 'ISEMPTY':
                        return userValue === '';
                    case 'ISNOTEMPTY':
                        return userValue !== '';
                    case 'BETWEEN':
                        var values3 = value.split('@');
                        return userValue && userValue >= values3[0] && userValue <= values3[1];
                    case 'SAMEAS':
                        userValue = (type == 'reference') ? g_form.getDisplayValue(term.field) : g_form.getValue(term.field);
                        value = (type == 'reference') ? g_form.getDisplayValue(term.value) : g_form.getValue(term.value);
                        return userValue == value;
                    case 'NSAMEAS':
                        userValue = (type == 'reference') ? g_form.getDisplayValue(term.field) : g_form.getValue(term.field);
                        value = (type == 'reference') ? g_form.getDisplayValue(term.value) : g_form.getValue(term.value);
                        return userValue != value;
                    default:
                        return false;
                }
            }
    
            function evaluateTermNumber(term) {
                var field = term.field;
                if (!field)
                    return false;
                var oper = term.oper;
                var value = term.value;
                if (value !== '' && value.indexOf(',') === -1)
                    value = parseFloat(value);
                var userValue = getUserValue(term);
                switch (oper) {
                    case '=':
                        return userValue === value;
                    case '!=':
                        return userValue != value;
                    case '<':
                        return userValue < value;
                    case '<=':
                        return userValue <= value;
                    case '>':
                        return userValue > value;
                    case '>=':
                        return userValue >= value;
                    case 'IN':
                        var values = (value + "").split(',');
                        return userValue.toString() && (_inArray(userValue.toString(), values) !== -1);
                    case 'NOT IN':
                        var values2 = (value + "").split(',');
                        return _inArray(userValue.toString(), values2) === -1;
                    case 'ISEMPTY':
                        return userValue.toString() === '';
                    case 'ISNOTEMPTY':
                        return userValue.toString() !== '';
                    case "GT_FIELD":
                        userValue = parseInt(g_form.getValue(term.field));
                        value = parseInt(g_form.getValue(term.value));
                        return userValue > value;
                    case "LT_FIELD":
                        userValue = parseInt(g_form.getValue(term.field));
                        value = parseInt(g_form.getValue(term.value));
                        return userValue < value;
                    case "GT_OR_EQUALS_FIELD":
                        userValue = parseInt(g_form.getValue(term.field));
                        value = parseInt(g_form.getValue(term.value));
                        return userValue >= value;
                    case "LT_OR_EQUALS_FIELD":
                        userValue = parseInt(g_form.getValue(term.field));
                        value = parseInt(g_form.getValue(term.value));
                        return userValue <= value;
                    default:
                        return false;
                }
            }
    
            function evaluateTermDate(term) {
                var value = term.value;
                var userValue = g_form.getValue(term.field) + '';
                var values = value.split('@');
                var isDateTime = uiPolicyTypes.dateTypes[term.type] == "datetime";
                if (!isDateTime)
                    userValue += " 00:00:00";
                if (term.oper == 'ISEMPTY')
                    return userValue === '';
                var userDate = _getDate(userValue);
                if (isNaN(userDate)) {
                    _debug("evaluateTermDate - invalid date, returning false");
                    return false;
                }
                if (term.oper == "RELATIVE")
                    return _evaluateTermDateRelative(userDate, value, isDateTime);
                if (term.oper == "DATEPART")
                    return _evaluateTermDateTrend(userDate, value);
                var valueDate, valueDate1, valueDate2;
                switch (term.oper) {
                    case '=':
                        return g_form.getValue(term.field) === value;
                    case '!=':
                        return g_form.getValue(term.field) != value;
                    case 'ISNOTEMPTY':
                        return userValue !== '';
                    case '<=':
                    case '<':
                        valueDate = _getDate(value);
                        return (valueDate !== 0) && (userDate < valueDate);
                    case '>=':
                    case '>':
                        valueDate = _getDate(value);
                        return (valueDate !== 0) && (userDate > valueDate);
                    case 'ON':
                        valueDate1 = _getDate(values[1]);
                        valueDate2 = _getDate(values[2]);
                        return (valueDate1 !== 0) && (valueDate2 !== 0) && (userDate >= valueDate1) && (userDate <= valueDate2);
                    case 'NOTON':
                        valueDate1 = _getDate(values[1]);
                        valueDate2 = _getDate(values[2]);
                        return (valueDate1 !== 0) && (valueDate2 !== 0) && ((userDate < valueDate1) || (userDate > valueDate2));
                    case 'BETWEEN':
                        valueDate1 = _getDate(values[0]);
                        valueDate2 = _getDate(values[1]);
                        return (valueDate1 !== 0) && (valueDate2 !== 0) && (userDate >= valueDate1) && (userDate <= valueDate2);
                    case 'LESSTHAN':
                        return _dateComparisonHelper(term.field, term.value, 'LT');
                    case 'MORETHAN':
                        return _dateComparisonHelper(term.field, term.value, 'GT');
                    default:
                        _debug("evaluateTermDate - unsupported operator '" + term.oper + "'. Returning FALSE.");
                        return false;
                }
            }
    
            function _dateComparisonHelper(left, right, comparison) {
                var parsed = _parseField2FieldValue(right);
                var userValue = g_form.getValue(left);
                var value = g_form.getValue(parsed.fieldName);
                if (_isNullField(value) || _isNullField(userValue)) {
                    _debug("ui policy could not find a valid field to compare against. Returning FALSE.");
                    return false;
                }
                var userDate = _getDate(userValue);
                var theDate = _getDate(value);
                if (parsed.interval == 'quarter') {
                    userDate = _roundDateToQuarter(userDate);
                    theDate = _roundDateToQuarter(theDate);
                }
                var diff = userDate - theDate;
                if (parsed.beforeAfter == 'before' && diff > 0)
                    return false;
                if (parsed.beforeAfter == 'after' && diff < 0)
                    return false;
                var xDiff;
                if (parsed.interval == 'quarter') {
                    var Qdiff = Math.abs(_getAbsQuarter(theDate) - _getAbsQuarter(userDate));
                    xDiff = Qdiff - parsed.intervalValue;
                } else {
                    var timeSpan = _getIntervalInMilliSeconds(parsed.interval, parsed.intervalValue);
                    xDiff = Math.abs(diff) - Math.abs(timeSpan);
                }
                if (comparison === 'GT')
                    return xDiff > 0;
                if (comparison === 'LT')
                    return xDiff < 0;
            }
    
            function _getAbsQuarter(theDate) {
                var quarters = [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4];
                var Q = quarters[theDate.getMonth()];
                var Y = theDate.getFullYear() * 4;
                return Y + Q;
            }
    
            function _roundDateToQuarter(theDate) {
                var quarters = [0, 0, 0, 3, 3, 3, 6, 6, 6, 9, 9, 9];
                var Q = quarters[theDate.getMonth()];
                var d = new Date();
                d.setFullYear(theDate.getFullYear(), Q, 0);
                d.setHours(0, 0, 0);
                return d;
            }
    
            function _isNullField(fieldValue) {
                return typeof fieldValue == 'undefined' || fieldValue == null || fieldValue == '';
            }
    
            function _parseField2FieldValue(daString) {
                var daArray = daString.split('@');
                return {
                    fieldName: daArray[0],
                    interval: daArray[1],
                    intervalValue: parseInt(daArray[3], 10),
                    beforeAfter: daArray[2]
                };
            }
    
            function _getIntervalInMilliSeconds(interval, value) {
                var ms = {};
                ms.hour = 1000 * 60 * 60;
                ms.day = ms.hour * 24;
                ms.week = ms.day * 7;
                ms.month = ms.day * 30;
                ms.year = ms.day * 365;
                return ms[interval] * value;
            }
    
            function _getDate(dateValue) {
                if (dateValue)
                    dateValue = dateValue.replace(/\s/, 'T');
                return new Date(dateValue);
            }
    
            function _evaluateTermDateTrend(userDateMilliseconds, trendValueString) {
                var userDate = new Date(userDateMilliseconds);
                var trendParams = trendValueString.split("@");
                if (trendParams.length != 2 || !trendParams[1])
                    return;
                var trendParamParts = trendParams[1].split(",");
                if (trendParamParts.length != 3)
                    return;
                var trendType = trendParamParts[0];
                var trendValue = trendParamParts[1];
                var trendOper = trendParamParts[2];
                var checkVals;
                switch (trendType) {
                    case 'dayofweek':
                        checkVals = _trendDayOfWeek(userDate, trendValue, trendOper);
                        break;
                    case 'month':
                        checkVals = _trendMonth(userDate, trendValue, trendOper);
                        break;
                    case 'year':
                        checkVals = _trendYear(userDate, trendValue, trendOper);
                        break;
                    case 'week':
                        checkVals = _trendWeek(userDate, trendValue, trendOper);
                        break;
                    case 'hour':
                        checkVals = _trendHour(userDate, trendValue, trendOper);
                        break;
                    case 'quarter':
                        checkVals = _trendQuarter(userDate, trendValue, trendOper);
                        break;
                    default:
                        _debug("_evaluateTermDateTrend - unsupported trend type '" + trendType + "'. Returning FALSE.");
                        return false;
                }
                return _evaluateDateValues(checkVals, trendOper);
            }
    
            function _evaluateTermDateRelative(userDateMilliseconds, relativeValueString, isDateTime) {
                var relativeValues = relativeValueString.split('@');
                if (!relativeValues || relativeValues.length != 4 || isNaN(relativeValues[3]))
                    return false;
                var oper = relativeValues[0];
                var termType = relativeValues[1];
                var termWhen = relativeValues[2];
                var termValue = parseInt(relativeValues[3], 10);
                var modifier = 1;
                if (termWhen == "ahead")
                    modifier = -1;
                var relativeValueMilliseconds;
                switch (termType) {
                    case 'hour':
                        relativeValueMilliseconds = hoursAgoInMilliseconds(modifier * termValue);
                        break;
                    case 'minute':
                        relativeValueMilliseconds = minutesAgoInMilliseconds(modifier * termValue);
                        break;
                    case 'dayofweek':
                        relativeValueMilliseconds = daysAgoInMilliseconds(modifier * termValue);
                        break;
                    case 'month':
                        relativeValueMilliseconds = monthsAgoInMilliseconds(modifier * termValue);
                        break;
                    case 'quarter':
                        relativeValueMilliseconds = quartersAgoInMilliseconds(modifier * termValue);
                        break;
                    case 'year':
                        relativeValueMilliseconds = yearsAgoInMilliseconds(modifier * termValue);
                        break;
                    default:
                        _debug("_evaluateTermDateRelative - unsupported type '" + termType + "'. Returning FALSE.");
                        return false;
                }
                var checkVals;
                if (isDateTime) {
                    checkVals = {
                        checkValue: relativeValueMilliseconds,
                        userValue: userDateMilliseconds
                    };
                } else {
                    checkVals = {
                        checkValue: _removeTime(relativeValueMilliseconds),
                        userValue: _removeTime(userDateMilliseconds)
                    };
                }
                return _evaluateDateValues(checkVals, oper);
            }
    
            function _evaluateDateValues(checkVals, oper) {
                if (!checkVals)
                    return;
                switch (oper) {
                    case 'EE':
                        return checkVals.userValue === checkVals.checkValue;
                    case 'LT':
                        return checkVals.userValue < checkVals.checkValue;
                    case 'LE':
                        return checkVals.userValue <= checkVals.checkValue;
                    case 'GT':
                        return checkVals.userValue > checkVals.checkValue;
                    case 'GE':
                        return checkVals.userValue >= checkVals.checkValue;
                    default:
                        _debug("_evaluateDateValues - unsupported operator '" + oper + "'. Returning FALSE.");
                        return false;
                }
            }
    
            function _removeTime(dateInMilliseconds) {
                var newDate = new Date(dateInMilliseconds);
                newDate.setHours(0);
                newDate.setMinutes(0);
                newDate.setSeconds(0);
                newDate.setMilliseconds(0);
                return newDate.getTime();
            }
    
            function _trendDayOfWeek(userDate, trendValue) {
                var trendDays = ['monday', 'tuesday', 'wednesday', 'thurday', 'friday', 'saturday', 'sunday'];
                var foundIn = -1;
                for (var i = 0; i < 7; i++)
                    if (trendDays[i] == trendValue) {
                        foundIn = i;
                        break;
                    }
                if (foundIn < 0)
                    return;
                var userDOW = userDate.getDay();
                userDOW = userDOW - 1;
                if (userDOW < 0)
                    userDOW = 6;
                return {
                    checkValue: foundIn,
                    userValue: userDOW
                };
            }
    
            function _trendMonth(userDate, trendValue) {
                var trendMonths = ['jan', 'feb', 'mar', 'apr', 'may', 'june', 'july', 'aug', 'sep', 'oct', 'nov', 'dec'];
                var foundIn = -1;
                for (var i = 0; i < 12; i++)
                    if (trendMonths[i] == trendValue) {
                        foundIn = i;
                        break;
                    }
                if (foundIn < 0)
                    return;
                return {
                    checkValue: foundIn,
                    userValue: userDate.getMonth()
                };
            }
    
            function _trendYear(userDate, trendValue) {
                return {
                    checkValue: trendValue,
                    userValue: userDate.getFullYear()
                };
            }
    
            function _trendHour(userDate, trendValue) {
                return {
                    checkValue: trendValue,
                    userValue: userDate.getHour()
                };
            }
    
            function _trendQuarter(userDate, trendValue) {
                var quarters = [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4];
                return {
                    checkValue: trendValue,
                    userValue: quarters[userDate.getMonth()]
                };
            }
    
            function _trendWeek(userDate, trendValue) {
                var checkDate = new Date(userDate.getFullYear(), 0, 1);
                var userWeek = (Math.ceil((((userDate.getTime() - checkDate) / 86400000) + checkDate.getDay() + 1) / 7)) - 1;
                return {
                    checkValue: trendValue,
                    userValue: userWeek
                };
            }
    
            function quartersAgoInMilliseconds(quarters) {
                var now = new Date();
                var quartersModifier = [0, 1, 1, 1, 4, 4, 4, 7, 7, 7, 10, 10, 10];
                var month = now.getMonth() + 1;
                var quarterBegin = quartersModifier[month];
                var monthsBack = month - quarterBegin + (quarters * 3);
                return monthsAgoInMilliseconds(monthsBack);
            }
    
            function yearsAgoInMilliseconds(years) {
                var now = new Date();
                var yearsAgo = now.getFullYear() - years;
                now.setFullYear(yearsAgo);
                return now.getTime(now);
            }
    
            function monthsAgoInMilliseconds(months) {
                var now = new Date();
                var monthsAgo = now.getMonth() - months;
                now.setMonth(monthsAgo);
                return now.getTime(now);
            }
    
            function daysAgoInMilliseconds(days) {
                return hoursAgoInMilliseconds(days * 24);
            }
    
            function hoursAgoInMilliseconds(hours) {
                return minutesAgoInMilliseconds(hours * 60);
            }
    
            function minutesAgoInMilliseconds(minutes) {
                return secondsAgoInMilliseconds(minutes * 60);
            }
    
            function secondsAgoInMilliseconds(seconds) {
                return new Date().getTime() - (seconds * 1000);
            }
    
            function getUserValue(term) {
                if (typeof g_form == "undefined")
                    return '';
                var userValue = g_form.getValue(term.field + ".storage") + '';
                if (userValue)
                    return g_form.getDecimalValue(term.field + ".storage");
                var uv = g_form.getValue(term.field);
                if (!uv || uv.length === 0)
                    return '';
                return g_form.getDecimalValue(term.field);
            }
    
            function runActions(result) {
                if (result === _lastResult) {
                    _debug("No change - not running any actions");
                    return;
                }
                _lastResult = result;
                if (result) {
                    for (var i = 0; i < uiPolicyMap.actions.length; i++) {
                        var action = uiPolicyMap.actions[i];
                        _runAction(action, result);
                    }
                    _runScript(uiPolicyMap.script_true.name);
                } else if (uiPolicyMap.reverse) {
                    for (var j = 0; j < uiPolicyMap.actions.length; j++) {
                        var action2 = uiPolicyMap.actions[j];
                        _runAction(action2, result);
                    }
                    _runScript(uiPolicyMap.script_false.name);
                }
            }
    
            function _runScript(name) {
                if (typeof name !== "string" || !name.length)
                    return;
                try {
                    scripts[name].execute();
                } catch (e) {
                    console.log("UI policy script error: " + e);
                }
            }
    
            function _runAction(action, result) {
                if (typeof g_form == "undefined")
                    return;
                var field = action.name,
                    mandatory = action.mandatory,
                    visible = action.visible,
                    disabled = action.disabled;
                if (mandatory == 'true') {
                    g_form.setMandatory(field, result);
                    _debugAction(field, "mandatory", result);
                } else if (mandatory == 'false') {
                    g_form.setMandatory(field, !result);
                    _debugAction(field, "mandatory", !result);
                }
                if (visible == 'true') {
                    g_form.setDisplay(field, result);
                    _debugAction(field, "visible", result);
                } else if (visible == 'false') {
                    g_form.setDisplay(field, !result);
                    _debugAction(field, "visible", !result);
                }
                if (disabled == 'true') {
                    g_form.setReadOnly(field, result);
                    _debugAction(field, "disabled", result);
                } else if (disabled == 'false') {
                    g_form.setReadOnly(field, !result);
                    _debugAction(field, "disabled", !result);
                }
                if (mandatory == 'true') {
                    g_form.setMandatory(field, result);
                    _debugAction(field, "mandatory", result);
                }
            }
    
            function _isField2FieldComparisonlOper(oper) {
                var special = [
                    "MORETHAN",
                    "LESSTHAN",
                    "GT_FIELD",
                    "LT_FIELD",
                    "GT_OR_EQUALS_FIELD",
                    "LT_OR_EQUALS_FIELD",
                    "SAMEAS",
                    "NSAMEAS"
                ];
                return special.indexOf(oper) > -1;
            }
    
            function _inArray(val, array) {
                if (Array.prototype.indexOf) {
                    return Array.prototype.indexOf.call(array, val);
                }
                for (var i = 0, iM = array.length; i < iM; i++) {
                    if (array[i] === val) {
                        return i;
                    }
                }
                return -1;
            }
    
            function _debugAction(field, action, flag) {
                if (!_isDebug) {
                    return;
                }
                _debug('Setting ' + action + ' on field:' + field + ' to ' + flag);
            }
    
            function _debug(msg) {
                if (!_isDebug) {
                    return;
                }
                console.log('(uiPolicyFactory)', msg);
            }
    
            function _debugTerm(term, result) {
                if (!_isDebug) {
                    return;
                }
                var or = "";
                if (term.or)
                    or = "  or ";
                var userValue;
                if (term.field)
                    userValue = g_form.getValue(term.field) + '';
                else
                    userValue = "(null)";
                if (!userValue)
                    userValue = "<blank>";
                var dspValue = "";
                if (dspValue)
                    dspValue = " [" + dspValue + "] ";
                if (result)
                    result = "true";
                else
                    result = "false";
                _debug(or + term.field + " " + "(" + userValue + dspValue + ") " + term.oper + " " + term.value + " -> " + result);
            }
        }
    })(window);;
    /*! RESOURCE: /scripts/sn/common/clientScript/glideFormEnvironmentFactory.js */
    (function(exports, $log, undefined) {
        'use strict';
        var factory = exports.glideFormEnvironmentFactory = {
            create: createGlideFormEnvironment,
            defaultExtensionPoints: {
                'window': null,
                'document': null,
                '$': null,
                'jQuery': null,
                '$$': null,
                '$j': null,
                'angular': null,
                'snmCabrillo': null,
                'cabrillo': null
            }
        };
    
        function createGlideFormEnvironment(g_form, g_scratchpad, g_user, g_modal) {
            if (typeof g_user === 'undefined' || !g_user) {
                throw 'g_user is required!';
            }
            if (typeof g_scratchpad === 'undefined' || !g_scratchpad) {
                g_scratchpad = {};
            }
            var _extensionPoints = {
                g_scratchpad: extend(g_scratchpad, {}, true),
                g_user: typeof g_user.clone === 'function' ? g_user.clone() : g_user
            };
            if (typeof g_modal !== 'undefined') {
                _extensionPoints['g_modal'] = g_modal;
            }
            var defaults = factory.defaultExtensionPoints;
            Object.keys(defaults).forEach(function(name) {
                registerExtensionPoint(name, defaults[name]);
            });
            var _isFormLoading = true;
            var _isTemplateLoading = false;
            var _onChangeScripts = {};
            var _onSubmitScripts = [];
            return {
                initScripts: initScripts,
                initUIPolicyScripts: initUIPolicyScripts,
                getExtensionPoints: getExtensionPoints,
                registerExtensionPoint: registerExtensionPoint
            };
    
            function initScripts(scriptMap) {
                var cs, script;
                var onLoadScripts = [];
                if (scriptMap.onLoad) {
                    for (var i = 0; i < scriptMap.onLoad.length; i++) {
                        try {
                            cs = scriptMap.onLoad[i];
                            script = _wrapScript(cs.script, null, 'onLoad');
                            onLoadScripts.push(_wrapExecuteClientScript(script, g_form, cs.name));
                        } catch (e) {
                            _logError('CS:ONLOAD', 'Could not load onLoad Client Script "' + cs.name + '": ' + e);
                        }
                    }
                }
                if (scriptMap.onChange) {
                    for (var j = 0; j < scriptMap.onChange.length; j++) {
                        try {
                            cs = scriptMap.onChange[j];
                            script = _wrapScript(cs.script, ['control', 'oldValue', 'newValue', 'isLoading', 'isTemplate'], 'onChange');
                            if (!_onChangeScripts[cs.fieldName]) {
                                _onChangeScripts[cs.fieldName] = [];
                            }
                            _onChangeScripts[cs.fieldName].push(
                                _wrapExecuteClientScript(script, g_form, cs.name)
                            );
                        } catch (e) {
                            _logError('CS:ONCHANGE', 'Could not load onChange Client Script "' + cs.name + '": ' + e);
                        }
                    }
                }
                if (scriptMap.onSubmit) {
                    for (var k = 0; k < scriptMap.onSubmit.length; k++) {
                        try {
                            cs = scriptMap.onSubmit[k];
                            script = _wrapScript(cs.script, null, 'onSubmit');
                            _onSubmitScripts.push(
                                _wrapExecuteClientScript(script, g_form, cs.name)
                            );
                        } catch (e) {
                            _logError('CS:ONSUBMIT', 'Could not load onSubmit Client Script "' + cs.name + '": ' + e);
                        }
                    }
                }
                _onLoadForm(onLoadScripts);
            }
    
            function initUIPolicyScripts(uiPolicies) {
                uiPolicies.forEach(function(uiPolicyMap) {
                    var scripts = _initUIPolicyMap(uiPolicyMap);
                    var uiPolicy = uiPolicyFactory.create(g_form, uiPolicyMap, scripts);
                });
            }
    
            function getExtensionPoints() {
                return extend(_extensionPoints, {}, true);
            }
    
            function registerExtensionPoint(name, value) {
                if (_extensionPoints.hasOwnProperty(name)) {
                    $log.warn('Overwriting extension point: ' + name);
                }
                _extensionPoints[name] = value;
            }
    
            function _initUIPolicyMap(uiPolicyMap) {
                var resultScriptMap = {};
                ['script_true', 'script_false'].forEach(function(type) {
                    var policyScript = uiPolicyMap[type];
                    if (!policyScript) {
                        return;
                    }
                    try {
                        var wrappedScript = _wrapScript(policyScript.script);
                        resultScriptMap[policyScript.name] = {
                            execute: _wrapExecuteClientScript(wrappedScript, g_form, uiPolicyMap.short_description)
                        };
                    } catch (e) {
                        var errType = type.toUpperCase();
                        _logError('UI:' + errType, 'Could not load UIPolicy script for policy "' + uiPolicyMap.short_description + '"');
                    }
                });
                return resultScriptMap;
            }
    
            function _onLoadForm(onLoadScripts) {
                for (var i = 0, iM = onLoadScripts.length; i < iM; i++) {
                    onLoadScripts[i].call(null);
                }
                g_form.$private.events.on('change', _onChangeForm);
                g_form.$private.events.on('submit', _onSubmitForm);
                var value;
                Object.keys(_onChangeScripts).forEach(function(fieldName) {
                    value = g_form.getValue(fieldName);
                    _onChangeForm(fieldName, value, value);
                });
                _isFormLoading = false;
            }
    
            function _onChangeForm(fieldName, oldValue, newValue) {
                var scripts = _onChangeScripts[fieldName];
                if (scripts) {
                    var scriptVariables = {
                        control: null,
                        oldValue: oldValue,
                        newValue: newValue,
                        isLoading: !!_isFormLoading,
                        isTemplate: !!_isTemplateLoading
                    };
                    scripts.forEach(function(script) {
                        script.call(null, scriptVariables);
                    });
                }
            }
    
            function _onSubmitForm() {
                var result;
                for (var i = 0, iM = _onSubmitScripts.length; i < iM; i++) {
                    result = _onSubmitScripts[i].call(null);
                    if (result === false) {
                        return result;
                    }
                }
            }
    
            function _wrapScript(script, parameters, mainFuncName) {
                var scriptParams = parameters || [];
                var allParams = scriptParams.slice(0);
                allParams = allParams.concat('g_form', Object.keys(getExtensionPoints()));
                var fn;
                try {
                    fn = new Function(allParams, 'return (' + script + ')(' + scriptParams.join(',') + ')');
                } catch (e) {
                    if (mainFuncName) {
                        script = new Function([], script + ' return ' + mainFuncName + '.apply(this, arguments);');
                        fn = new Function(allParams, 'return (' + script + ')(' + scriptParams.join(',') + ')');
                    } else
                        throw e;
                }
                fn.$inject = allParams;
                return fn;
            }
    
            function _wrapExecuteClientScript(script, g_form, name) {
                return function(apiParams) {
                    return _executeClientScript(script, g_form, name, apiParams);
                };
            }
    
            function _executeClientScript(script, g_form, name, apiParams) {
                var injectedParams = apiParams || {};
                if (typeof injectedParams === 'string') {
                    _logError('SCRIPT:EXEC', 'Invalid params passed into Client Script "' + name + '"');
                    return;
                }
                var baseParams = {
                    g_form: g_form
                };
                extend(injectedParams, baseParams);
                extend(injectedParams, getExtensionPoints());
                try {
                    var result = _invoke(script, this, injectedParams);
                    return result;
                } catch (e) {
                    _logError('SCRIPT:EXEC', 'Error while running Client Script "' + name + '": ' + e);
                }
            }
    
            function _invoke(fn, self, locals) {
                var $inject = fn.$inject;
                if (typeof $inject === 'undefined') {
                    throw 'Missing $inject. Did you try calling externally?';
                }
                var key;
                var args = [];
                for (var i = 0, iM = $inject.length; i < iM; i++) {
                    key = $inject[i];
                    if (typeof key !== 'string') {
                        throw 'Invalid injection key provided: ' + key;
                    }
                    var arg = locals[key];
                    if (typeof arg === 'undefined') {
                        throw 'Injection argument not found (' + key + ')';
                    }
                    args.push(arg);
                }
                return fn.apply(self, args);
            }
    
            function extend(defaults, options, newObject) {
                var extended = newObject === true ? {} : defaults;
                var prop;
                for (prop in defaults) {
                    if (Object.prototype.hasOwnProperty.call(defaults, prop)) {
                        extended[prop] = defaults[prop];
                    }
                }
                for (prop in options) {
                    if (Object.prototype.hasOwnProperty.call(options, prop)) {
                        extended[prop] = options[prop];
                    }
                }
                return extended;
            }
    
            function _logError(code, msg) {
                if ($log && $log.error) {
                    $log.error('(g_env) [' + code + '] ' + msg);
                }
            }
        }
    })(window, console);;
    /*! RESOURCE: /scripts/sn/common/clientScript/glideRequest.js */
    (function(exports, undefined) {
        'use strict';
        var glideRequest = {
            getAngularURL: function(path, parameters) {
                return 'angular.do?sysparm_type=' + path + (parameters ? encodeURIParameters(parameters) : '');
            },
            get: function(url, options) {
                if (!url) {
                    throw 'Must specify a URL';
                }
                var fetchOptions = _applyOptions('get', url, options);
                return exports.fetch(fetchOptions.url, fetchOptions);
            },
            post: function(url, options) {
                if (!url) {
                    throw 'Must specify a URL';
                }
                var fetchOptions = _applyOptions('post', url, options);
                return exports.fetch(fetchOptions.url, fetchOptions);
            }
        };
    
        function _applyOptions(method, url, options) {
            var fetchOptions = {
                method: method,
                url: url
            };
            switch (method) {
                case 'get':
                    var url = fetchOptions.url;
                    if (options.data) {
                        var params = encodeURIParameters(options.data);
                        if (url.indexOf('?') !== -1) {
                            url += '&' + params;
                        } else {
                            url += '?' + params;
                        }
                    }
                    fetchOptions.url = url;
                    break;
                case 'post':
                    fetchOptions.url = options.url;
                    fetchOptions.body = JSON.stringify(options.data || {});
                    break;
            }
            switch (options.dataType) {
                default:
                    case 'json':
                    fetchOptions.headers = {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json',
                    'X-UserToken': window.g_ck
                };
                break;
                case 'xml':
                        fetchOptions.headers = {
                        'Accept': 'application/xml',
                        'Content-Type': 'application/xml',
                        'X-UserToken': window.g_ck
                    };
                    break;
            }
            return fetchOptions;
        }
    
        function encodeURIParameters(parameters) {
            var s = [];
            for (var parameter in parameters) {
                if (parameters.hasOwnProperty(parameter)) {
                    var key = encodeURIComponent(parameter);
                    var value = parameters[parameter] ? encodeURIComponent(parameters[parameter]) : '';
                    s.push(key + "=" + value);
                }
            }
            return s.join('&');
        }
        exports.glideRequest = glideRequest;
    })(window);;
    /*! RESOURCE: /scripts/sn/common/clientScript/glideAjax.js */
    (function(exports, undefined) {
        'use strict';
        var url = '/xmlhttp.do';
        var logError = function() {
            if (console && console.error)
                console.error.apply(console, arguments);
        };
    
        function GlideAjax() {
            this.initialize.apply(this, arguments);
        }
        GlideAjax.glideRequest = exports.glideRequest;
        GlideAjax.logError = logError;
        GlideAjax.prototype = {
            initialize: function(targetProcessor, targetURL) {
                this.processor = null;
                this.params = {};
                this.callbackFn = function() {};
                this.errorCallbackFn = function(e) {
                    GlideAjax.logError('Unhandled exception in GlideAjax.', e.responseText);
                };
                this.wantAnswer = false;
                this.requestObject = null;
                this.setProcessor(targetProcessor);
                url = targetURL || url;
            },
            addParam: function(name, value) {
                this.params[name] = value;
            },
            getXML: function(callback) {
                this.wantAnswer = false;
                this.callbackFn = callback;
                this.execute();
            },
            getXMLWait: function() {
                GlideAjax.logError('GlideAjax.getXMLWait is no longer supported');
            },
            getXMLAnswer: function(callback) {
                this.wantAnswer = true;
                this.callbackFn = callback;
                this.execute();
            },
            getAnswer: function() {
                return this.responseXML ? this.responseXML.documentElement.getAttribute('answer') : null;
            },
            setErrorCallback: function(errorCallback) {
                this.errorCallbackFn = errorCallback;
            },
            getURL: function() {
                return url;
            },
            getParams: function() {
                return this.params;
            },
            setProcessor: function(p) {
                this.addParam('sysparm_processor', p);
                if (!p) {
                    GlideAjax.logError('GlideAjax.initalize: must specify a processor');
                }
                this.processor = p;
            },
            execute: function() {
                var that = this;
                GlideAjax.glideRequest.post(url, {
                        data: this.params,
                        dataType: 'xml'
                    })
                    .then(function(response) {
                        that.responseXML = response.responseXML;
                        that.responseText = response.responseText;
                        var ajaxResponse = {
                            type: response.type,
                            responseText: response.responseText,
                            responseXML: response.responseXML
                        };
                        var args = [
                            that.wantAnswer ? that.getAnswer() : ajaxResponse
                        ];
                        try {
                            that.callbackFn.apply(null, args);
                        } catch (e) {
                            if (that.errorCallbackFn) {
                                that.errorCallbackFn({
                                    type: 'unhandled exception',
                                    responseText: e.message
                                });
                            } else
                                GlideAjax.logError('Unhandled exception in GlideAjax callback.', e);
                        }
                    })
                    .catch(function(error) {
                        var errorResponse = {
                            type: error.type,
                            status: error.status,
                            responseText: error.responseText,
                            responseXML: error.responseXML
                        };
                        if (that.errorCallbackFn) {
                            that.errorCallbackFn(errorResponse);
                        }
                    });
            },
            setScope: function(scope) {
                if (scope) {
                    this.addParam('sysparm_scope', scope);
                }
                return this;
            }
        };
        exports.GlideAjax = GlideAjax;
    })(window);;
    /*! RESOURCE: /scripts/sn/common/clientScript/glideRecord.js */
    (function(exports, undefined) {
        'use strict';
    
        function GlideRecord(table) {
            if (!(this instanceof GlideRecord)) {
                return new GlideRecord(table);
            }
            this.initialize.apply(this, arguments);
        }
        GlideRecord.glideRequest = exports.glideRequest;
        GlideRecord.prototype = {
            initialize: function(table) {
                this.tableName = table;
                this.encodedQuery = '';
                this.conditions = [];
                this.orderByFields = [];
                this.limit = 0;
                this._callback = null;
                this.currentRow = -1;
                this.recordSet = [];
            },
            addQuery: function() {
                var args = [];
                Array.prototype.push.apply(args, arguments);
                var name = args.shift(),
                    oper, value;
                oper = args.length == 1 ? "=" : args.shift();
                value = args.shift();
                this.conditions.push({
                    'name': name,
                    'oper': oper,
                    'value': value
                });
            },
            setEncodedQuery: function(queryString) {
                this.encodedQuery = queryString;
            },
            getEncodedQuery: function() {
                var qc = [];
                var ec = this.encodedQuery;
                if (ec) {
                    qc.push(ec);
                }
                for (var i = 0; i < this.conditions.length; i++) {
                    var q = this.conditions[i];
                    qc.push(q['name'] + q['oper'] + q['value']);
                }
                return '^' + qc.join('^');
            },
            addOrderBy: function(field) {
                this.orderByFields.push(field);
            },
            setLimit: function(maxRows) {
                this.limit = maxRows;
            },
            getLimit: function() {
                return this.limit;
            },
            get: function() {
                this.initialize(this.tableName);
                this.setLimit(1);
                var callback;
                if (arguments.length == 2) {
                    this.addQuery('sys_id', arguments[0]);
                    callback = arguments[1];
                } else if (arguments.length == 3) {
                    this.addQuery(arguments[0], arguments[1]);
                    callback = arguments[2];
                }
                if (!callback) {
                    _logWarn('GET:NOCB', 'Get must be called with a callback function');
                    return;
                }
                this.query(this._getResponse.bind(this, callback));
            },
            _getResponse: function(callback) {
                this.next();
                callback(this);
            },
            query: function(callback) {
                if (typeof callback !== 'function') {
                    _logWarn('Q:NOCB', 'Query must be called with a callback function');
                    return;
                }
                var glideRequest = GlideRecord.glideRequest;
                var src = glideRequest.getAngularURL('gliderecord', {
                    operation: 'query'
                });
                glideRequest.post(src, {
                    dataType: 'json',
                    data: {
                        table: this.tableName,
                        query: this.getEncodedQuery(),
                        orderBy: this.orderByFields.join(','),
                        limit: this.getLimit()
                    }
                }).then(this._queryResponse.bind(this, callback));
            },
            _queryResponse: function(callback, response) {
                this._loadRecordSet(response.data.records);
                callback(this);
            },
            deleteRecord: function() {
                _logError('UNSUPPORTED', 'deleteRecord is not supported on mobile');
            },
            update: function() {
                _logError('UNSUPPORTED', 'update is not supported on mobile');
            },
            hasNext: function() {
                return this.currentRow + 1 < this.recordSet.length;
            },
            next: function() {
                if (!this.hasNext())
                    return false;
                this.loadRow(this.currentRow + 1);
                return true;
            },
            loadRow: function(index) {
                var row = this.recordSet[index];
                this.currentRow = index;
                var currentRow = this.getCurrentRow();
                for (var i in currentRow) {
                    if (!currentRow.hasOwnProperty(i)) {
                        continue;
                    }
                    this[i] = currentRow[i].value;
                }
            },
            _loadRecordSet: function(records) {
                this.recordSet = records || [];
            },
            getValue: function(fieldName) {
                var current = this.getCurrentRow();
                return current ? current[fieldName].value : '';
            },
            getDisplayValue: function(fieldName) {
                var current = this.getCurrentRow();
                if (!fieldName) {
                    return current ? current['$$displayValue'] : '';
                }
                return current ? current[fieldName].displayvalue : '';
            },
            getCurrentRow: function() {
                return this.recordSet[this.currentRow];
            },
            getRowCount: function() {
                return this.recordSet.length;
            },
            getTableName: function() {
                return this.tableName;
            },
            toString: function() {
                return 'GlideRecord';
            }
        };
    
        function _logError(code, msg) {
            if (console && console.error) {
                console.error('(GlideRecord) [' + code + '] ' + msg);
            }
        }
    
        function _logWarn(code, msg) {
            if (console && console.warn) {
                console.warn('(GlideRecord) [' + code + '] ' + msg);
            }
        }
        exports.GlideRecord = GlideRecord;
    })(window);;
    /*! RESOURCE: /scripts/sn/common/clientScript/glideUser.js */
    (function(exports, undefined) {
        'use strict';
        var ROLE_MAINT = 'maint';
        var ROLE_ADMIN = 'admin';
    
        function GlideUser(fields) {
            if (!(this instanceof GlideUser)) {
                return new GlideUser(fields);
            }
            var _firstName = fields.firstName || null;
            var _lastName = fields.lastName || null;
            var _userName = fields.userName || null;
            var _userId = fields.userID || null;
            var _roles = fields.roles || null;
            var _allRoles = fields.allRoles || null;
            var _email = fields.email || null;
            var _title = fields.title || null;
            var _avatar = fields.avatar || null;
            var _clientData = fields.clientData || {};
            Object.defineProperties(this, {
                firstName: {
                    get: function() {
                        return _firstName;
                    }
                },
                lastName: {
                    get: function() {
                        return _lastName;
                    }
                },
                userName: {
                    get: function() {
                        return _userName;
                    }
                },
                userID: {
                    get: function() {
                        return _userId;
                    }
                },
                title: {
                    get: function() {
                        return _title;
                    }
                },
                email: {
                    get: function() {
                        return _email;
                    }
                },
                avatar: {
                    get: function() {
                        return _avatar;
                    }
                }
            });
            this.getFullName = function() {
                return _firstName + ' ' + _lastName;
            };
            this.getClientData = function(key) {
                return _clientData[key];
            };
            this.hasRoles = function(includeDefaults) {
                if (includeDefaults)
                    return _allRoles && (_allRoles.length > 0);
                else
                    return _roles && (_roles.length > 0);
            };
            this.hasRoleExactly = function(role, includeDefaults) {
                if (!this.hasRoles(includeDefaults) || !role || (typeof role !== 'string')) {
                    return false;
                }
                var normalizedRole = role.toLowerCase();
                var rolesToCheck = _roles;
                if (includeDefaults)
                    rolesToCheck = _allRoles;
                for (var i = 0, iM = rolesToCheck.length; i < iM; i++) {
                    if (normalizedRole === rolesToCheck[i].toLowerCase()) {
                        return true;
                    }
                }
                return false;
            };
            this.hasRole = function(role, includeDefaults) {
                if (!this.hasRoles(includeDefaults)) {
                    return false;
                }
                if (this.hasRoleExactly(ROLE_MAINT, includeDefaults)) {
                    return true;
                } else if (role === ROLE_MAINT) {
                    return false;
                }
                if (this.hasRoleExactly(role, includeDefaults)) {
                    return true;
                }
                if (this.hasRoleExactly(ROLE_ADMIN, includeDefaults)) {
                    return true;
                }
                return false;
            };
            this.hasRoleFromList = function(roles, includeDefaults) {
                if (!this.hasRoles(includeDefaults)) {
                    return false;
                }
                var checkRoles = roles;
                if (typeof roles === 'string') {
                    checkRoles = roles.split(/\s*,\s*/);
                }
                if (checkRoles.length === 0) {
                    return true;
                }
                for (var i = 0, iM = checkRoles.length; i < iM; i++) {
                    var role = checkRoles[i];
                    if (role && this.hasRole(role, includeDefaults)) {
                        return true;
                    }
                }
                return false;
            };
            this.clone = function() {
                return new GlideUser(fields);
            };
        }
        exports.GlideUser = GlideUser;
    })(window);;;
    /*! RESOURCE: /scripts/sn/common/clientScript/angular/js_includes_angular.js */
    /*! RESOURCE: /scripts/sn/common/clientScript/angular/_module.js */
    angular.module('sn.common.clientScript', [
        'sn.common.i18n',
        'sn.common.util'
    ]);;
    /*! RESOURCE: /scripts/sn/common/clientScript/angular/glideAjaxFactory.js */
    angular.module('sn.common.clientScript').factory('glideAjaxFactory', function($window, glideRequest) {
        $window.GlideAjax.glideRequest = glideRequest;
        return {
            create: function(processor) {
                return new $window.GlideAjax(processor);
            },
            getClass: function() {
                return $window.GlideAjax;
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/clientScript/angular/glideFormEnvironmentFactory.js */
    angular.module('sn.common.clientScript').factory('glideFormEnvironmentFactory', function(
        $q,
        $window,
        $timeout,
        glideFormFieldFactory,
        glideAjaxFactory,
        glideRecordFactory,
        i18n,
        glideModalFactory,
        jQueryRequestShim
    ) {
        'use strict';
        var factory = $window.glideFormEnvironmentFactory;
        angular.extend(factory.defaultExtensionPoints, {
            GlideAjax: glideAjaxFactory.getClass(),
            GlideRecord: glideRecordFactory.getClass(),
            getMessage: i18n.getMessage,
            getMessages: i18n.getMessages,
            $: jQueryRequestShim
        });
        factory.createInitializer = function(g_form, g_user, g_scratchpad, clientScripts, uiPolicies, g_modal) {
            if (typeof g_modal === 'undefined') {
                g_modal = glideModalFactory.create();
            }
            var g_env = glideFormEnvironmentFactory.create(g_form, g_scratchpad, g_user, g_modal);
            if (clientScripts && clientScripts.messages) {
                for (var key in clientScripts.messages) {
                    i18n.loadMessage(key, clientScripts.messages[key]);
                }
            }
            return function() {
                g_env.initScripts(clientScripts);
                if (uiPolicies && (uiPolicies.length > 0)) {
                    g_env.initUIPolicyScripts(uiPolicies);
                }
                return g_env;
            };
        };
        factory.createWithConfiguration = function(g_form, g_user, g_scratchpad, clientScripts, uiPolicies, g_modal) {
            if (typeof g_modal === 'undefined') {
                g_modal = glideModalFactory.create();
            }
            var g_env = glideFormEnvironmentFactory.create(g_form, g_scratchpad, g_user, g_modal);
            if (clientScripts && clientScripts.messages) {
                for (var key in clientScripts.messages) {
                    i18n.loadMessage(key, clientScripts.messages[key]);
                }
            }
            return {
                g_env: g_env,
                initialize: function() {
                    g_env.initScripts(clientScripts);
                    if (uiPolicies && (uiPolicies.length > 0)) {
                        g_env.initUIPolicyScripts(uiPolicies);
                    }
                }
            };
        };
        var FIELDS_INITIALIZED_INTERVAL = 195;
        factory.onFieldsInitialized = function(fields) {
            var $fieldsReady = $q.defer();
            var $readyTimeout = $timeout(checkFormFields, FIELDS_INITIALIZED_INTERVAL);
    
            function checkFormFields() {
                var ready = fields.reduce(function(previous, field) {
                    return previous && glideFormFieldFactory.isInitialized(field);
                }, true);
                if (!ready) {
                    $readyTimeout = $timeout(checkFormFields, FIELDS_INITIALIZED_INTERVAL);
                    return;
                }
                $fieldsReady.resolve();
            }
            return $fieldsReady.promise;
        };
        return factory;
    });;
    /*! RESOURCE: /scripts/sn/common/clientScript/angular/glideFormFactory.js */
    angular.module('sn.common.clientScript').factory('glideFormFactory', function($window, glideRecordFactory, glideRequest, glideFormMessageHandler) {
        'use strict';
        var factory = $window.glideFormFactory;
        factory.glideRequest = glideRequest;
        var EVENT_CHANGED = 'changed';
        var EVENT_PROPERTY_CHANGE = 'propertyChange';
    
        function createAngularGlideForm($scope, tableName, sysId, fields, uiActions, options, relatedLists, sections) {
            options = angular.extend({
                GlideRecord: glideRecordFactory.getClass(),
                uiMessageHandler: glideFormMessageHandler
            }, options);
            var g_form = factory.create(tableName, sysId, fields, uiActions, options, relatedLists, sections);
            g_form.$private.events.on(EVENT_CHANGED, function() {
                if (!$scope.$root.$$phase) {
                    $scope.$apply();
                }
            });
            g_form.$private.events.on(EVENT_PROPERTY_CHANGE, function() {
                if (!$scope.$root.$$phase) {
                    $scope.$apply();
                }
            });
            $scope.$on('$destroy', function() {
                g_form.$private.events.cleanup();
            });
            return g_form;
        }
        return {
            create: createAngularGlideForm
        }
    });;
    /*! RESOURCE: /scripts/sn/common/clientScript/angular/glideFormFieldFactory.js */
    angular.module('sn.common.clientScript').factory('glideFormFieldFactory', function($window) {
        'use strict';
        return $window.glideFormFieldFactory;
    });;
    /*! RESOURCE: /scripts/sn/common/clientScript/angular/glideFormMessageHandler.js */
    angular.module('sn.common.clientScript').factory('glideFormMessageHandler', function($rootScope) {
        'use strict';
        return function(g_form, type, message) {
            switch (type) {
                case 'infoMessage':
                    $rootScope.$emit('snm.ui.sessionNotification', {
                        type: 'info',
                        message: message
                    });
                    break;
                case 'errorMessage':
                    $rootScope.$emit('snm.ui.sessionNotification', {
                        type: 'error',
                        message: message
                    });
                    break;
                case 'clearMessages':
                    break;
                default:
                    return false;
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/clientScript/angular/glideListFactory.js */
    angular.module('sn.common.clientScript').factory('glideListFactory', function() {
        'use strict';
        if (typeof g_glide_list_separator == "undefined")
            var g_glide_list_separator = ", ";
        return {
            init: init
        };
    
        function init(g_form, fields) {
            return {
                get: function(fieldName) {
                    return _glideListUtil(fieldName, g_form, fields);
                }
            };
        }
    
        function getField(fieldName, g_form, fields) {
            for (var i = 0, iM = fields.length; i < iM; i++) {
                var field = fields[i];
                if (field.variable_name === fieldName || field.name === fieldName) {
                    return field;
                }
            }
            if (g_form.$private.options('getMappedField')) {
                var mapped = g_form.$private.options('getMappedField')(fieldName);
                if (mapped) {
                    return mapped;
                }
            }
        }
    
        function _glideListUtil(fieldName, g_form, fields) {
            var field = getField(fieldName, g_form, fields);
            if (!field)
                return;
    
            function addItem(item, itemDV) {
                var v = field.value;
                if (v.indexOf(item) > -1)
                    return;
                var dv = field.display_value_list;
                v = v == '' ? [] : v.split(',');
                if (v.indexOf(item) == -1) {
                    v.push(item);
                    dv.push(itemDV);
                }
                g_form.setValue(fieldName, v.join(','), dv.join(g_glide_list_separator));
            }
    
            function removeItem(item) {
                var v = field.value;
                if (v.indexOf(item) == -1)
                    return;
                var values = field.value.split(',');
                var displayValues = field.display_value_list;
                for (var i = values.length - 1; i >= 0; i--) {
                    if (item == values[i]) {
                        values.splice(i, 1);
                        displayValues.splice(i, 1);
                        break;
                    }
                }
                g_form.setValue(field.name, values.join(','), displayValues.join(g_glide_list_separator));
            }
    
            function reset() {
                field.ed.queryString = '';
            }
    
            function setQuery(queryString) {
                field.ed.queryString = queryString;
                field.ed.queryString.replace("^EQ", "");
            }
    
            function setDefaultOperator(operator) {
                field.ed.defaultOperator = operator;
            }
    
            function getDefaultOperator() {
                return field.ed.defaultOperator;
            }
            return {
                addItem: addItem,
                removeItem: removeItem,
                setQuery: setQuery,
                getDefaultOperator: getDefaultOperator,
                setDefaultOperator: setDefaultOperator,
                queryString: field.ed.queryString,
                reset: reset
            };
        }
    });;
    /*! RESOURCE: /scripts/sn/common/clientScript/angular/glideModalFactory.js */
    angular.module('sn.common.clientScript').factory('glideModalFactory', function($q) {
        'use strict';
        return {
            create: create
        };
    
        function create(options) {
            options = options || {};
            var alertHandler = options.alert || _browserAlertHandler;
            var confirmHandler = options.confirm || _browserConfirmHandler;
            return {
                alert: function() {
                    var args = _getArgs(arguments);
                    var $d = $q.defer();
                    if (args.callback) {
                        $d.promise.then(function() {
                            args.callback();
                        });
                    }
                    if (alertHandler) {
                        alertHandler(args.title, args.message, function() {
                            $d.resolve();
                        });
                    } else {
                        $d.reject();
                    }
                    return $d.promise;
                },
                confirm: function() {
                    var args = _getArgs(arguments);
                    var $d = $q.defer();
                    if (args.callback) {
                        $d.promise.then(function(result) {
                            args.callback(result);
                        });
                    }
                    if (confirmHandler) {
                        confirmHandler(args.title, args.message, function(result) {
                            $d.resolve(result === true ? true : false);
                        });
                    } else {
                        $d.reject();
                    }
                    return $d.promise;
                }
            };
        }
    
        function _getArgs(args) {
            var title = args[0];
            var message = args[1];
            var callback = args[2];
            switch (typeof message) {
                case 'function':
                    callback = message;
                case 'undefined':
                    message = title;
                    title = null;
                    break;
                default:
                    break;
            }
            return {
                title: title,
                message: message,
                callback: callback
            };
        }
    
        function _browserAlertHandler(title, message, done) {
            alert(message);
            done();
        }
    
        function _browserConfirmHandler(title, message, done) {
            done(confirm(message));
        }
    });;
    /*! RESOURCE: /scripts/sn/common/clientScript/angular/glideRecordFactory.js */
    angular.module('sn.common.clientScript').factory('glideRecordFactory', function($window, glideRequest) {
        $window.GlideRecord.glideRequest = glideRequest;
        return {
            create: function(table) {
                return new $window.GlideRecord(table);
            },
            getClass: function() {
                return $window.GlideRecord;
            }
        };
    });;
    /*! RESOURCE: /scripts/sn/common/clientScript/angular/glideRequest.js */
    angular.module('sn.common.clientScript').factory('glideRequest', function($q, $log, $http, $window, urlTools, xmlUtil) {
        'use strict';
        $window.glideRequest = {
            getAngularURL: urlTools.getURL,
            get: $http.get,
            post: function(url, options) {
                options = options || {};
                options.url = url;
                options.method = 'post';
                if (!options.headers) {
                    options.headers = {};
                }
                var getXml = false;
                switch (options.dataType) {
                    case 'json':
                        break;
                    case 'xml':
                        options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
                        var data = options.data || {};
                        options.data = urlTools.encodeURIParameters(data);
                        getXml = true;
                        options.responseType = 'text';
                        if (!options.data) {
                            options.data = '';
                        }
                        options.headers['Accept'] = 'application/xml, text/xml';
                        break;
                    default:
                }
                return $http(options).then(function(response) {
                    response.type = getXml ? 'xml' : 'json';
                    response.responseText = response.data;
                    response.responseXML = getXml ? xmlUtil.xmlToElement(response.data) : null;
                    return response;
                }, function(error) {
                    error.type = getXml ? 'xml' : 'json';
                    error.responseText = error.data;
                    error.responseXML = getXml ? xmlUtil.xmlToElement(error.data) : null;
                    return $q.reject(error);
                });
            }
        };
        return $window.glideRequest;
    });;
    /*! RESOURCE: /scripts/sn/common/clientScript/angular/glideUserFactory.js */
    angular.module('sn.common.clientScript').factory('glideUserFactory', function($window) {
        function getClass() {
            return $window.GlideUser;
        }
        return {
            create: function(fields) {
                var u = getClass();
                return new u(fields);
            },
            getClass: getClass
        };
    });;
    /*! RESOURCE: /scripts/sn/common/clientScript/angular/jQueryRequestShim.js */
    angular.module('sn.common.clientScript').factory('jQueryRequestShim', function(glideRequest) {
        if (angular.isDefined(window.jQuery)) {
            return {
                get: window.jQuery.get,
                post: window.jQuery.post
            };
        }
        var jQueryRequestShim = {
            get: function() {
                var args = Array.prototype.slice.call(arguments);
                return _createJQueryRequest('get', args);
            },
            post: function() {
                var args = Array.prototype.slice.call(arguments);
                return _createJQueryRequest('post', args);
            }
        };
    
        function _createJQueryRequest(type, args) {
            var url = args.shift() || '';
            var data = args.shift();
            var success;
            if (typeof data === 'function') {
                success = data;
                data = null;
            } else {
                success = args.shift();
            }
            var dataType = args.shift();
            if (!angular.isDefined(dataType)) {
                dataType = 'json';
            }
            var $request;
            switch (type) {
                case 'get':
                    $request = glideRequest.get(url);
                    break;
                case 'post':
                    $request = glideRequest.post(url, {
                        data: data,
                        dataType: dataType
                    });
                    break;
            }
            if (success) {
                $request = $request.then(function(response) {
                    success(response.data, response.statusText, response);
                });
            }
            return $request;
        }
        return jQueryRequestShim;
    });;
    /*! RESOURCE: /scripts/sn/common/clientScript/angular/uiPolicyFactory.js */
    angular.module('sn.common.clientScript').factory('uiPolicyFactory', function($window) {
        var factory = $window.uiPolicyFactory;
        return factory;
    });;
    /*! RESOURCE: /scripts/sn/common/clientScript/angular/uiPolicyTypes.js */
    angular.module('sn.common.clientScript').factory('uiPolicyTypes', function($window) {
        var factory = $window.UI_POLICY_TYPES;
        return factory;
    });;
    /*! RESOURCE: /scripts/sn/common/clientScript/angular/xmlUtil.js */
    angular.module('sn.common.clientScript').factory('xmlUtil', function($log) {
        function xmlToElement(xmlText) {
            if (typeof DOMParser !== 'undefined') {
                try {
                    var parser = new DOMParser();
                    return parser.parseFromString(xmlText, 'application/xml');
                } catch (e) {
                    $log.error(e);
                    return null;
                }
            } else {
                var xml = angular.element(xmlText);
                $log.warn('DOMParser is not supported on this browser');
                return angular.element(xml[1]);
            }
        }
    
        function getDataFromXml(text, nodeName) {
            var dataSet = [];
            var el = angular.element(xmlToElement(text));
            if (el && el.length) {
                var nodes = angular.isString(nodeName) ? el.find(nodeName) : el.find('xml');
                angular.forEach(nodes, function(n) {
                    if (n.attributes && n.attributes.length) {
                        var data = {};
                        angular.forEach(n.attributes, function(attr) {
                            data[attr.nodeName] = attr.nodeValue;
                        });
                        dataSet.push(data);
                    }
                });
            }
            return dataSet;
        }
        return {
            xmlToElement: xmlToElement,
            getDataFromXml: getDataFromXml
        };
    });;;
    /*! RESOURCE: /scripts/snm/serviceCatalog/form/js_includes_form.js */
    /*! RESOURCE: /scripts/snm/serviceCatalog/form/snm.serviceCatalog.form.module.js */
    angular.module('snm.serviceCatalog.form', [
        'sn.common.clientScript',
        'sn.common.util'
    ]);;
    /*! RESOURCE: /scripts/snm/serviceCatalog/form/catalogDataLookup.js */
    angular.module('snm.serviceCatalog.form').factory('catalogDataLookup', function($q, $log, $http, urlTools) {
        'use strict';
        var DEBUG_LOG = false;
        return {
            initItem: initItem,
            initRecord: initRecord
        };
    
        function initItem(itemSysId, g_form) {
            var url = urlTools.getURL('catalog_data_lookup', {
                item: itemSysId
            });
            return _loadDataLookup(url, itemSysId, g_form);
        }
    
        function initRecord(itemSysId, g_form, tableName, recordSysId) {
            var url = urlTools.getURL('catalog_form_data_lookup', {
                table: tableName,
                sys_id: recordSysId
            });
            return _loadDataLookup(url, itemSysId, g_form);
        }
    
        function _loadDataLookup(url, itemSysId, g_form) {
            return $http.get(url).then(function(response) {
                var data = response.data;
                if (!data.catalog_data_lookup) {
                    return null;
                }
                if (DEBUG_LOG) {
                    $log.log('(catalogDataLookup) Loaded:', data);
                }
                return _createDataLookupEnv(itemSysId, g_form, data.catalog_data_lookup);
            });
        }
    
        function _createDataLookupEnv(itemSysId, g_form, dataLookups) {
            var fieldDataLookups = {};
            for (var i = 0, iM = dataLookups.length; i < iM; i++) {
                var dld = dataLookups[i];
                var fields = dld.fields;
                for (var j = 0, jM = fields.length; j < jM; j++) {
                    var fieldName = fields[j];
                    if (g_form.hasField(fieldName)) {
                        var fieldDataLookup = fieldDataLookups[fieldName];
                        if (!fieldDataLookup) {
                            fieldDataLookup = fieldDataLookups[fieldName] = {
                                dlds: []
                            };
                        }
                        fieldDataLookup.dlds.push(dld);
                    }
                }
            }
            g_form.serviceCatalog = {
                activeDataLookupRequests: [],
                lastDataLookup: null,
                dataLookupDisabled: false
            };
            var onChange = _wrapChangeHandler(itemSysId, g_form, fieldDataLookups);
            g_form.$private.events.on('change', onChange);
            return {
                created: true
            };
        }
    
        function _wrapChangeHandler(_itemSysId, _g_form, _fieldDataLookups) {
            var itemSysId = _itemSysId;
            var g_form = _g_form;
            var fieldDataLookups = _fieldDataLookups;
            return function _onChangeForm(control, oldValue, newValue, isLoading, isTemplate) {
                var dataLookup = fieldDataLookups[control];
                if (!dataLookup || !dataLookup.dlds) {
                    return;
                }
                if (DEBUG_LOG) {
                    $log.log('(catalogDataLookup) Found field lookup:', control, dataLookup);
                }
                var $activeLookups = [];
                for (var i = 0, iM = dataLookup.dlds.length; i < iM; i++) {
                    var $lookup = _runDataLookup(itemSysId, dataLookup.dlds[i], g_form);
                    if ($lookup) {
                        $activeLookups.push($lookup);
                    }
                }
                if ($activeLookups.length == 0) {
                    return;
                }
                var $requests = $q.all($activeLookups).finally(function() {
                    g_form.serviceCatalog.activeDataLookupRequests.pop();
                });
                g_form.serviceCatalog.activeDataLookupRequests.push($requests)
            };
        }
    
        function _runDataLookup(itemSysId, dld, g_form) {
            if (g_form.serviceCatalog.dataLookupDisabled) {
                return;
            }
            var getFieldParams = g_form.$private.options('getFieldParams');
            var fieldParams = getFieldParams();
            var serialized = urlTools.encodeURIParameters(fieldParams);
            if (g_form.serviceCatalog.lastDataLookup === serialized) {
                return;
            }
            g_form.serviceCatalog.lastDataLookup = serialized;
            var tableName = g_form.getTableName();
            if (!tableName) {
                tableName = "ni";
            }
            var sysId = g_form.getSysId();
            if (typeof sysId === 'undefined') {
                sysId = '';
            }
            var url = urlTools.getURL('run_catalog_data_lookup');
            var getFieldSequence = g_form.$private.options('getFieldSequence');
            var requestFields = angular.extend({}, fieldParams, {
                sys_target: tableName,
                sysparm_id: itemSysId,
                data_lookup_sys_id: dld.data_lookup_sys_id,
                variable_sequence1: getFieldSequence()
            });
            return $http({
                method: 'POST',
                url: url,
                data: urlTools.encodeURIParameters(requestFields),
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                }
            }).then(function(response) {
                var data = response.data;
                if (!data.fields) {
                    return;
                }
                g_form.serviceCatalog.dataLookupDisabled = true;
                for (var i = 0; i < data.fields.length; i++) {
                    var field = data.fields[i];
                    if (field.label === '' || field.value === '') {
                        continue;
                    }
                    g_form.setValue(field.name, field.value, field.label);
                }
                g_form.serviceCatalog.dataLookupDisabled = false;
            });
        }
    });;
    /*! RESOURCE: /scripts/snm/serviceCatalog/form/catalogGlideFormFactory.js */
    angular.module('snm.serviceCatalog.form').factory('catalogGlideFormFactory', function($q, $log, $http, urlTools, glideFormFactory, catalogDataLookup) {
        'use strict';
        return {
            addVariableEditor: addVariableEditor,
            addItemEditor: addItemEditor
        };
    
        function addItemEditor(g_form, itemSysId, tableName, sysId, fields) {
            var options = _getGlideFormOptions(itemSysId, fields);
            g_form.$private.options(options);
            catalogDataLookup.initItem(itemSysId, g_form, tableName, sysId);
        }
    
        function addVariableEditor(g_form, itemSysId, tableName, sysId, fields) {
            var options = _getGlideFormOptions(itemSysId, fields);
            g_form.$private.options(options);
            catalogDataLookup.initRecord(itemSysId, g_form, tableName, sysId);
        }
    
        function _getGlideFormOptions(itemSysId, fields) {
            var catalogFields = getCatalogFields(fields);
            var options = {
                getMappedField: function(fieldName) {
                    return getCatalogField(catalogFields, fieldName);
                },
                getMappedFieldName: function(fieldName) {
                    var field = getCatalogField(catalogFields, fieldName);
                    return field.variable_name || field.catalogFieldName;
                },
                getFieldParams: function() {
                    return getFieldParams(catalogFields);
                },
                getFieldSequence: function() {
                    return getFieldSequence(catalogFields);
                },
                itemSysId: itemSysId
            };
            return options;
        }
    
        function getCatalogFields(fields, arr) {
            if (!arr) {
                arr = [];
            }
            for (var i = 0; i < fields.length; i++) {
                var field = fields[i];
                field.catalogFieldName = getCatalogFieldName(field.name, field.sys_id);
                arr.push(field);
                if (field.fields && field.fields.length > 0) {
                    getCatalogFields(field.fields, arr);
                }
            }
            return arr;
        }
    
        function getCatalogField(fields, fieldName) {
            for (var i = 0, iM = fields.length; i < iM; i++) {
                if (fields[i].name === fieldName || fields[i].catalogFieldName == fieldName || fields[i].variable_name == fieldName) {
                    return fields[i];
                }
            }
            return null;
        }
    
        function getCatalogFieldName(name, sysId) {
            var prefix = 'IO:';
            if (name.indexOf('ni.QS') === 0) {
                prefix = 'ni.QS';
            }
            return prefix + sysId;
        }
    
        function getFieldParams(fieldList) {
            var params = {};
            for (var i = 0; i < fieldList.length; i++) {
                var field = fieldList[i];
                var sysId = field.sys_id;
                if (!sysId || sysId.indexOf("gen_") == 0) {
                    continue;
                }
                switch (field.catalogType) {
                    default: var prefix = field.name.indexOf('ni.QS') === 0 ? 'ni.QS' : 'IO';
                    params[prefix + ':' + sysId] = field.value;
                    params['sys_original.' + prefix + ':' + sysId] = field.initial_value;
                    switch (field.type) {
                        case 'masked':
                            if (prefix === 'IO') {
                                params['ni.nolog.IO:' + sysId] = true
                            } else {
                                params['ni.nolog.QS:' + sysId] = true
                            }
                            break;
                        case 'checkbox':
                            params[prefix + ':' + sysId] = field.value == 'true' ? 'on' : '';
                            break;
                    }
                    break;
                    case 'quantity':
                            params[sysId] = field.value;
                        break;
                    case 'label':
                            case 'break':
                            break;
                }
            }
            return params;
        }
    
        function getFieldSequence(fieldList) {
            var sequence = [];
            for (var i = 0; i < fieldList.length; i++) {
                var field = fieldList[i];
                if (field.catalogType !== 'quantity') {
                    if (!field.sys_id || field.sys_id.indexOf("gen_") == 0) {
                        continue;
                    }
                    var result = field.sys_id;
                    if (result != "") {
                        sequence.push(result);
                    }
                }
            }
            return sequence.join(',');
        }
    });;;
    /*! RESOURCE: /scripts/snm/serviceCatalog/data/snm.serviceCatalog.data.shim.js */
    angular.module('snm.data', []);
    angular.module('snm.serviceCatalog.data', ['snm.data']);;
    /*! RESOURCE: /scripts/snm/data/glideRecordData.js */
    angular.module('snm.data').factory('glideRecordData', function($q, $http, urlTools) {
        'use strict';
    
        function loadRecord(tableName, sysId, viewName, queryFields) {
            var record = new GlideRecordData(tableName, 'sys_id', sysId, viewName, queryFields);
            return record.load();
        }
    
        function loadRecordByKey(tableName, referenceKey, referenceValue, viewName, queryFields) {
            if (typeof referenceKey === 'undefined' || referenceKey == null) {
                referenceKey = 'sys_id';
            }
            var record = new GlideRecordData(tableName, referenceKey, referenceValue, viewName, queryFields);
            return record.load();
        }
    
        function GlideRecordData(tableName, referenceKey, referenceValue, viewName, queryFields) {
            this.tableName = tableName;
            this.referenceKey = referenceKey;
            this.referenceValue = referenceValue;
            this.viewName = viewName;
            this.queryFields = typeof queryFields === 'string' ? _parseQueryFields(queryFields) : queryFields;
        }
        var NEW_SYS_ID = '-1';
        angular.extend(GlideRecordData.prototype, {
            getDisplayTitle: function() {
                return this.displayTitle;
            },
            isNewRecord: function() {
                return this.referenceValue === NEW_SYS_ID;
            },
            getField: function(fieldName) {
                for (var i = 0, iM = this.fields.length; i < iM; i++) {
                    if (this.fields[i].name == fieldName) {
                        return this.fields[i];
                    }
                }
            },
            load: function() {
                var queryParams = {
                    table: this.tableName,
                    reference_key: this.referenceKey,
                    sys_id: this.referenceValue,
                    query: null,
                    sysparm_extended_metadata: true
                };
                if (this.viewName != null && typeof this.viewName !== 'undefined') {
                    queryParams['sysparm_view'] = this.viewName;
                }
                var url = urlTools.getURL('record_data', queryParams);
                var record = this;
                return $http.get(url).then(function(response) {
                    var data = response.data;
                    if (typeof data.sys_id === 'undefined' && typeof data.table === 'undefined') {
                        return $q.reject({
                            status: 404
                        });
                    }
                    record.sysId = data.sys_id;
                    record.displayTitle = data.$$title;
                    var formFields = [];
                    data.fields.forEach(function(field) {
                        switch (field.name) {
                            case '.end_split':
                            case '.start_split':
                                break;
                            default:
                                formFields.push(field);
                                break;
                        }
                    });
                    record.fields = formFields;
                    record.variables = null;
                    if (data.variables && data.variables.length > 0) {
                        var variables = mapCatalogFieldTypes(data.variables);
                        variables.forEach(function(variable) {
                            record.fields.push(variable);
                        });
                        record.variables = variables;
                    }
                    record.itemSysId = data.itemSysId;
                    record.label = data.label;
                    record.encodedRecord = data.encoded_record || '';
                    record.relatedLists = data.relatedLists;
                    record.uiPolicy = data.policy;
                    record.uiActions = data.actions;
                    record.clientScripts = data.client_script;
                    record.g_scratchpad = data.g_scratchpad;
                    _applyQueryFields(record);
                    return record;
                });
            }
        });
    
        function mapCatalogFieldTypes(fields) {
            var mappedFields = [];
            fields.forEach(function(field) {
                var fieldType = field.type;
                field.is_variable = true;
                if (field.ref_table && !field.refTable) {
                    field.refTable = field.ref_table;
                }
                field.dbType = fieldType;
                field.catalogType = fieldType;
                if (field.fields) {
                    field.fields = mapCatalogFieldTypes(field.fields);
                }
                switch (fieldType) {
                    case 1:
                        field.catalogType = 'yesno';
                        field.type = 'choice';
                        break;
                    case 2:
                        field.catalogType = 'multilinetext';
                        field.type = 'text_area';
                        break;
                    case 3:
                        field.catalogType = 'multiplechoice';
                        field.type = 'choice';
                        break;
                    case 4:
                        field.catalogType = 'numericscale';
                        field.type = 'integer';
                        break;
                    case 100:
                        field.catalogType = 'quantity';
                        field.type = 'choice';
                        break;
                    case 5:
                        field.catalogType = 'selectbox';
                        field.type = 'choice';
                        break;
                    case 6:
                        field.catalogType = 'singlelinetext';
                        field.type = 'string';
                        break;
                    case 7:
                        field.catalogType = 'checkbox';
                        field.type = 'boolean';
                        break;
                    case 8:
                        field.type = 'reference';
                        break;
                    case 9:
                        field.catalogType = 'date';
                        field.type = 'glide_date';
                        break;
                    case 10:
                        field.catalogType = 'datetime';
                        field.type = 'glide_date_time';
                        break;
                    case 11:
                        field.type = 'label';
                        break;
                    case 12:
                        field.type = 'break';
                        break;
                    case 0:
                        field.catalogType = 'block_container';
                        field.type = 'block_container';
                        break;
                    case 99:
                        field.catalogType = 'checkbox_container';
                        field.type = 'checkbox_container';
                        break;
                    case 14:
                        field.type = 'macro';
                        break;
                    case 15:
                        field.type = 'uipage';
                        break;
                    case 16:
                        field.catalogType = 'widesinglelinetext';
                        field.type = 'string';
                        break;
                    case 17:
                        field.type = 'macrowithlabel';
                        break;
                    case 18:
                        field.type = 'lookupselectbox';
                        break;
                    case 19:
                        field.type = 'containerstart';
                        break;
                    case 20:
                        field.type = 'containerend';
                        break;
                    case 21:
                        field.type = 'listcollector';
                        break;
                    case 22:
                        field.type = 'lookupmultiplechoice';
                        break;
                    case 23:
                        field.type = 'html';
                        break;
                    case 24:
                        field.catalogType = 'containersplit';
                        field.type = 'split';
                        return;
                        break;
                    case 25:
                        field.type = 'masked';
                        break;
                    default:
                        $log.warn('Unknown field type:', fieldType);
                }
                mappedFields.push(field);
            });
            return mappedFields;
        }
    
        function _parseQueryFields(fields) {
            var splitFields = fields.split('^');
            var fields = {};
            splitFields.forEach(function(fieldPair) {
                var field = fieldPair.split('=', 2);
                fields[field[0]] = field[1];
            });
            return fields;
        }
    
        function _applyQueryFields(record) {
            if (record.isNewRecord() && record.queryFields) {
                var queryFields = record.queryFields;
                record.fields.forEach(function(field) {
                    field.dirtyQueryField = false;
                    var fieldValue = queryFields[field.name];
                    if (typeof fieldValue !== 'undefined') {
                        if (field.value !== fieldValue) {
                            field.dirtyQueryField = true;
                        }
                        field.value = fieldValue;
                    }
                });
            }
        }
        return {
            NEW_SYS_ID: NEW_SYS_ID,
            loadRecord: loadRecord,
            loadRecordByKey: loadRecordByKey,
            mapCatalogFieldTypes: mapCatalogFieldTypes
        };
    });;
    /*! RESOURCE: /scripts/snm/serviceCatalog/data/catalogItemFactory.js */
    angular.module('snm.serviceCatalog.data').factory('catalogItemFactory', function(
        $q,
        $log,
        $http,
        glideRecordData,
        urlTools
    ) {
        'use strict';
        var DEBUG_LOG = false;
        var TYPE_ITEM = 'item';
        var TYPE_PRODUCER = 'producer';
    
        function loadItem(categorySysId, itemSysId, type) {
            switch (type) {
                case TYPE_ITEM:
                case TYPE_PRODUCER:
                    break;
                default:
                    type = TYPE_ITEM;
            }
            var url = urlTools.getURL('catalog_item', {
                type: type,
                sys_id: itemSysId,
                category_sys_id: categorySysId
            });
            return $http.get(url).then(function(response) {
                var data = response.data;
                if (DEBUG_LOG) {
                    $log.log('(catalogItemFactory) loadItem', data);
                }
                return createCatalogItem(response.data, type);
            });
        }
    
        function loadProducer(categorySysId, itemSysId) {
            return loadItem(categorySysId, itemSysId, TYPE_PRODUCER).then(function(item) {
                angular.extend(item, {
                    recordParams: {
                        tableName: item.table,
                        sysId: item.sysparm_item_guid
                    }
                });
                return item;
            });
        }
    
        function createCatalogItem(data, itemType, viewLayout) {
            if (!data.type) {
                data.type = itemType;
            }
            if (data.fields) {
                data.fields = glideRecordData.mapCatalogFieldTypes(data.fields);
            }
            if (data.item_sys_id) {
                data.sysId = data.item_sys_id;
                data.cartItemSysId = data.sys_id;
            } else {
                data.sysId = data.sys_id;
            }
            if (data.category_sys_id) {
                data.categorySysId = data.category_sys_id;
            }
            if (data.picture && (data.picture !== 'sc_placeholder_image.png')) {
                data.pictureUrl = '/' + data.picture;
            }
            angular.extend(data, {
                getTitle: function() {
                    if (typeof data.displayValue === 'undefined') {
                        return data.name;
                    }
                    return data.name;
                },
                getDescription: function() {
                    if (data.getTitle() == data.short_description) {
                        return '';
                    }
                    return data.short_description;
                },
                getCategoryTitle: function() {
                    var total = data.breadcrumbs.length;
                    return data.breadcrumbs[total - 2].displayValue;
                },
                getPrice: function() {
                    return data.price_raw ? data.price_raw : parseFloat(data.price.replace(/\$|,/g, ''));
                },
                getRecurringPrice: function() {
                    return data.recurring_price_raw ? data.recurring_price_raw : parseFloat(data.recurring_price.replace(/\$|,/g, ''));
                },
                hasDescription: function() {
                    if (viewLayout && !viewLayout.sc_descriptions) {
                        return false;
                    }
                    return true;
                },
                hasQuantity: function() {
                    if (viewLayout && !viewLayout.sc_quantity) {
                        return false;
                    }
                    return !data.no_quantity ? data.quantity > 1 : false;
                },
                hasPrice: function() {
                    if (viewLayout && !viewLayout.sc_price) {
                        return false;
                    }
                    return data.price !== -1;
                },
                hasRecurring: function() {
                    if (viewLayout && !viewLayout.sc_recurring_price) {
                        return false;
                    }
                    return data.recurring_price !== -1;
                }
            });
            return data;
        }
    
        function loadItemScripts(itemSysId) {
            return $q.all([loadItemUiPolicy(itemSysId), loadItemClientScripts(itemSysId)]).then(function(results) {
                return {
                    uiPolicy: results[0],
                    clientScripts: results[1]
                };
            });
        }
    
        function loadItemUiPolicy(itemSysId) {
            var url = urlTools.getURL('catalog_ui_policy', {
                item: itemSysId
            });
            return $http.get(url).then(function(response) {
                var data = response.data;
                if (DEBUG_LOG) {
                    $log.log('(catalogItemFactory) loadItemUiPolicy', data);
                }
                return data.policy || [];
            });
        }
    
        function loadItemClientScripts(itemSysId) {
            var url = urlTools.getURL('catalog_client_script', {
                item: itemSysId
            });
            return $http.get(url).then(function(response) {
                var data = response.data;
                if (DEBUG_LOG) {
                    $log.log('(catalogItemFactory) loadItemClientScripts', data);
                }
                return data;
            });
        }
    
        function executeProducerSubmit(itemSysId, itemGuid, fieldParams, fieldSequence) {
            var requestFields = angular.extend({}, fieldParams, {
                type: 'produce_record',
                sysparm_action: 'execute_producer',
                sysparm_item_guid: itemGuid,
                sysparm_id: itemSysId,
                variable_sequence: fieldSequence
            });
            var url = urlTools.getURL('catalog_item');
            return $http({
                method: 'post',
                url: url,
                data: urlTools.encodeURIParameters(requestFields),
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded; charset=iso-8859-1'
                }
            }).then(function(response) {
                if (DEBUG_LOG) {
                    $log.log('(catalogItemFactory) producerSubmit', data);
                }
                var data = response.data;
                return data;
            });
        }
        return {
            TYPE_ITEM: TYPE_ITEM,
            TYPE_PRODUCER: TYPE_PRODUCER,
            loadItem: loadItem,
            loadProducer: loadProducer,
            loadItemScripts: loadItemScripts,
            executeProducerSubmit: executeProducerSubmit,
            create: createCatalogItem
        };
    });;
    /*! RESOURCE: /scripts/js_includes_sp_tinymce.js */
    /*! RESOURCE: /scripts/sp-tinymce/tinymce.min.js */
  • ¶

    4.3.3 (2016-01-14)

    ! function(e, t) {
        "use strict";
    
        function n(e, t) {
            for (var n, r = [], i = 0; i < e.length; ++i) {
                if (n = s[e[i]] || o(e[i]), !n) throw "module definition dependecy not found: " + e[i];
                r.push(n)
            }
            t.apply(null, r)
        }
    
        function r(e, r, i) {
            if ("string" != typeof e) throw "invalid module definition, module id must be defined and be a string";
            if (r === t) throw "invalid module definition, dependencies must be specified";
            if (i === t) throw "invalid module definition, definition function must be specified";
            n(r, function() {
                s[e] = i.apply(null, arguments)
            })
        }
    
        function i(e) {
            return !!s[e]
        }
    
        function o(t) {
            for (var n = e, r = t.split(/[.\/]/), i = 0; i < r.length; ++i) {
                if (!n[r[i]]) return;
                n = n[r[i]]
            }
            return n
        }
    
        function a(n) {
            var r, i, o, a, l;
            for (r = 0; r < n.length; r++) {
                i = e, o = n[r], a = o.split(/[.\/]/);
                for (var c = 0; c < a.length - 1; ++c) i[a[c]] === t && (i[a[c]] = {}), i = i[a[c]];
                i[a[a.length - 1]] = s[o]
            }
            if (e.AMDLC_TESTS) {
                l = e.privateModules || {};
                for (o in s) l[o] = s[o];
                for (r = 0; r < n.length; r++) delete l[n[r]];
                e.privateModules = l
            }
        }
        var s = {},
            l = "tinymce/geom/Rect",
            c = "tinymce/util/Promise",
            u = "tinymce/util/Delay",
            d = "tinymce/dom/EventUtils",
            f = "tinymce/dom/Sizzle",
            h = "tinymce/Env",
            p = "tinymce/util/Arr",
            m = "tinymce/util/Tools",
            g = "tinymce/dom/DomQuery",
            v = "tinymce/html/Styles",
            y = "tinymce/dom/TreeWalker",
            b = "tinymce/dom/Range",
            C = "tinymce/html/Entities",
            x = "tinymce/dom/StyleSheetLoader",
            w = "tinymce/dom/DOMUtils",
            E = "tinymce/dom/ScriptLoader",
            N = "tinymce/AddOnManager",
            _ = "tinymce/dom/NodeType",
            S = "tinymce/text/Zwsp",
            k = "tinymce/caret/CaretContainer",
            T = "tinymce/dom/RangeUtils",
            R = "tinymce/NodeChange",
            A = "tinymce/html/Node",
            B = "tinymce/html/Schema",
            D = "tinymce/html/SaxParser",
            M = "tinymce/html/DomParser",
            L = "tinymce/html/Writer",
            P = "tinymce/html/Serializer",
            H = "tinymce/dom/Serializer",
            O = "tinymce/dom/TridentSelection",
            I = "tinymce/util/VK",
            F = "tinymce/dom/ControlSelection",
            z = "tinymce/util/Fun",
            W = "tinymce/caret/CaretCandidate",
            V = "tinymce/geom/ClientRect",
            U = "tinymce/text/ExtendingChar",
            $ = "tinymce/caret/CaretPosition",
            q = "tinymce/caret/CaretBookmark",
            j = "tinymce/dom/BookmarkManager",
            Y = "tinymce/dom/Selection",
            X = "tinymce/dom/ElementUtils",
            K = "tinymce/fmt/Preview",
            G = "tinymce/Formatter",
            J = "tinymce/UndoManager",
            Q = "tinymce/EnterKey",
            Z = "tinymce/ForceBlocks",
            ee = "tinymce/EditorCommands",
            te = "tinymce/util/URI",
            ne = "tinymce/util/Class",
            re = "tinymce/util/EventDispatcher",
            ie = "tinymce/data/Binding",
            oe = "tinymce/util/Observable",
            ae = "tinymce/data/ObservableObject",
            se = "tinymce/ui/Selector",
            le = "tinymce/ui/Collection",
            ce = "tinymce/ui/DomUtils",
            ue = "tinymce/ui/BoxUtils",
            de = "tinymce/ui/ClassList",
            fe = "tinymce/ui/ReflowQueue",
            he = "tinymce/ui/Control",
            pe = "tinymce/ui/Factory",
            me = "tinymce/ui/KeyboardNavigation",
            ge = "tinymce/ui/Container",
            ve = "tinymce/ui/DragHelper",
            ye = "tinymce/ui/Scrollable",
            be = "tinymce/ui/Panel",
            Ce = "tinymce/ui/Movable",
            xe = "tinymce/ui/Resizable",
            we = "tinymce/ui/FloatPanel",
            Ee = "tinymce/ui/Window",
            Ne = "tinymce/ui/MessageBox",
            _e = "tinymce/WindowManager",
            Se = "tinymce/ui/Tooltip",
            ke = "tinymce/ui/Widget",
            Te = "tinymce/ui/Progress",
            Re = "tinymce/ui/Notification",
            Ae = "tinymce/NotificationManager",
            Be = "tinymce/dom/NodePath",
            De = "tinymce/util/Quirks",
            Me = "tinymce/EditorObservable",
            Le = "tinymce/Mode",
            Pe = "tinymce/Shortcuts",
            He = "tinymce/file/Uploader",
            Oe = "tinymce/file/Conversions",
            Ie = "tinymce/file/ImageScanner",
            Fe = "tinymce/file/BlobCache",
            ze = "tinymce/EditorUpload",
            We = "tinymce/caret/CaretUtils",
            Ve = "tinymce/caret/CaretWalker",
            Ue = "tinymce/caret/FakeCaret",
            $e = "tinymce/dom/Dimensions",
            qe = "tinymce/caret/LineWalker",
            je = "tinymce/caret/LineUtils",
            Ye = "tinymce/DragDropOverrides",
            Xe = "tinymce/SelectionOverrides",
            Ke = "tinymce/Editor",
            Ge = "tinymce/util/I18n",
            Je = "tinymce/FocusManager",
            Qe = "tinymce/EditorManager",
            Ze = "tinymce/LegacyInput",
            et = "tinymce/util/XHR",
            tt = "tinymce/util/JSON",
            nt = "tinymce/util/JSONRequest",
            rt = "tinymce/util/JSONP",
            it = "tinymce/util/LocalStorage",
            ot = "tinymce/Compat",
            at = "tinymce/ui/Layout",
            st = "tinymce/ui/AbsoluteLayout",
            lt = "tinymce/ui/Button",
            ct = "tinymce/ui/ButtonGroup",
            ut = "tinymce/ui/Checkbox",
            dt = "tinymce/ui/ComboBox",
            ft = "tinymce/ui/ColorBox",
            ht = "tinymce/ui/PanelButton",
            pt = "tinymce/ui/ColorButton",
            mt = "tinymce/util/Color",
            gt = "tinymce/ui/ColorPicker",
            vt = "tinymce/ui/Path",
            yt = "tinymce/ui/ElementPath",
            bt = "tinymce/ui/FormItem",
            Ct = "tinymce/ui/Form",
            xt = "tinymce/ui/FieldSet",
            wt = "tinymce/ui/FilePicker",
            Et = "tinymce/ui/FitLayout",
            Nt = "tinymce/ui/FlexLayout",
            _t = "tinymce/ui/FlowLayout",
            St = "tinymce/ui/FormatControls",
            kt = "tinymce/ui/GridLayout",
            Tt = "tinymce/ui/Iframe",
            Rt = "tinymce/ui/Label",
            At = "tinymce/ui/Toolbar",
            Bt = "tinymce/ui/MenuBar",
            Dt = "tinymce/ui/MenuButton",
            Mt = "tinymce/ui/MenuItem",
            Lt = "tinymce/ui/Menu",
            Pt = "tinymce/ui/ListBox",
            Ht = "tinymce/ui/Radio",
            Ot = "tinymce/ui/ResizeHandle",
            It = "tinymce/ui/SelectBox",
            Ft = "tinymce/ui/Slider",
            zt = "tinymce/ui/Spacer",
            Wt = "tinymce/ui/SplitButton",
            Vt = "tinymce/ui/StackLayout",
            Ut = "tinymce/ui/TabPanel",
            $t = "tinymce/ui/TextBox",
            qt = "tinymce/ui/Throbber";
        r(l, [], function() {
            function e(e, t, n) {
                var r, i, a, s, l, u;
                return r = t.x, i = t.y, a = e.w, s = e.h, l = t.w, u = t.h, n = (n || "").split(""), "b" === n[0] && (i += u), "r" === n[1] && (r += l), "c" === n[0] && (i += c(u / 2)), "c" === n[1] && (r += c(l / 2)), "b" === n[3] && (i -= s), "r" === n[4] && (r -= a), "c" === n[3] && (i -= c(s / 2)), "c" === n[4] && (r -= c(a / 2)), o(r, i, a, s)
            }
    
            function t(t, n, r, i) {
                var o, a;
                for (a = 0; a < i.length; a++)
                    if (o = e(t, n, i[a]), o.x >= r.x && o.x + o.w <= r.w + r.x && o.y >= r.y && o.y + o.h <= r.h + r.y) return i[a];
                return null
            }
    
            function n(e, t, n) {
                return o(e.x - t, e.y - n, e.w + 2 * t, e.h + 2 * n)
            }
    
            function r(e, t) {
                var n, r, i, a;
                return n = l(e.x, t.x), r = l(e.y, t.y), i = s(e.x + e.w, t.x + t.w), a = s(e.y + e.h, t.y + t.h), 0 > i - n || 0 > a - r ? null : o(n, r, i - n, a - r)
            }
    
            function i(e, t, n) {
                var r, i, a, s, c, u, d, f, h, p;
                return c = e.x, u = e.y, d = e.x + e.w, f = e.y + e.h, h = t.x + t.w, p = t.y + t.h, r = l(0, t.x - c), i = l(0, t.y - u), a = l(0, d - h), s = l(0, f - p), c += r, u += i, n && (d += r, f += i, c -= a, u -= s), d -= a, f -= s, o(c, u, d - c, f - u)
            }
    
            function o(e, t, n, r) {
                return {
                    x: e,
                    y: t,
                    w: n,
                    h: r
                }
            }
    
            function a(e) {
                return o(e.left, e.top, e.width, e.height)
            }
            var s = Math.min,
                l = Math.max,
                c = Math.round;
            return {
                inflate: n,
                relativePosition: e,
                findBestRelativePosition: t,
                intersect: r,
                clamp: i,
                create: o,
                fromClientRect: a
            }
        }), r(c, [], function() {
            function e(e, t) {
                return function() {
                    e.apply(t, arguments)
                }
            }
    
            function t(t) {
                if ("object" != typeof this) throw new TypeError("Promises must be constructed via new");
                if ("function" != typeof t) throw new TypeError("not a function");
                this._state = null, this._value = null, this._deferreds = [], s(t, e(r, this), e(i, this))
            }
    
            function n(e) {
                var t = this;
                return null === this._state ? void this._deferreds.push(e) : void l(function() {
                    var n = t._state ? e.onFulfilled : e.onRejected;
                    if (null === n) return void(t._state ? e.resolve : e.reject)(t._value);
                    var r;
                    try {
                        r = n(t._value)
                    } catch (i) {
                        return void e.reject(i)
                    }
                    e.resolve(r)
                })
            }
    
            function r(t) {
                try {
                    if (t === this) throw new TypeError("A promise cannot be resolved with itself.");
                    if (t && ("object" == typeof t || "function" == typeof t)) {
                        var n = t.then;
                        if ("function" == typeof n) return void s(e(n, t), e(r, this), e(i, this))
                    }
                    this._state = !0, this._value = t, o.call(this)
                } catch (a) {
                    i.call(this, a)
                }
            }
    
            function i(e) {
                this._state = !1, this._value = e, o.call(this)
            }
    
            function o() {
                for (var e = 0, t = this._deferreds.length; t > e; e++) n.call(this, this._deferreds[e]);
                this._deferreds = null
            }
    
            function a(e, t, n, r) {
                this.onFulfilled = "function" == typeof e ? e : null, this.onRejected = "function" == typeof t ? t : null, this.resolve = n, this.reject = r
            }
    
            function s(e, t, n) {
                var r = !1;
                try {
                    e(function(e) {
                        r || (r = !0, t(e))
                    }, function(e) {
                        r || (r = !0, n(e))
                    })
                } catch (i) {
                    if (r) return;
                    r = !0, n(i)
                }
            }
            if (window.Promise) return window.Promise;
            var l = t.immediateFn || "function" == typeof setImmediate && setImmediate || function(e) {
                    setTimeout(e, 1)
                },
                c = Array.isArray || function(e) {
                    return "[object Array]" === Object.prototype.toString.call(e)
                };
            return t.prototype["catch"] = function(e) {
                return this.then(null, e)
            }, t.prototype.then = function(e, r) {
                var i = this;
                return new t(function(t, o) {
                    n.call(i, new a(e, r, t, o))
                })
            }, t.all = function() {
                var e = Array.prototype.slice.call(1 === arguments.length && c(arguments[0]) ? arguments[0] : arguments);
                return new t(function(t, n) {
                    function r(o, a) {
                        try {
                            if (a && ("object" == typeof a || "function" == typeof a)) {
                                var s = a.then;
                                if ("function" == typeof s) return void s.call(a, function(e) {
                                    r(o, e)
                                }, n)
                            }
                            e[o] = a, 0 === --i && t(e)
                        } catch (l) {
                            n(l)
                        }
                    }
                    if (0 === e.length) return t([]);
                    for (var i = e.length, o = 0; o < e.length; o++) r(o, e[o])
                })
            }, t.resolve = function(e) {
                return e && "object" == typeof e && e.constructor === t ? e : new t(function(t) {
                    t(e)
                })
            }, t.reject = function(e) {
                return new t(function(t, n) {
                    n(e)
                })
            }, t.race = function(e) {
                return new t(function(t, n) {
                    for (var r = 0, i = e.length; i > r; r++) e[r].then(t, n)
                })
            }, t
        }), r(u, [c], function(e) {
            function t(e, t) {
                function n(e) {
                    window.setTimeout(e, 0)
                }
                var r, i = window.requestAnimationFrame,
                    o = ["ms", "moz", "webkit"];
                for (r = 0; r < o.length && !i; r++) i = window[o[r] + "RequestAnimationFrame"];
                i || (i = n), i(e, t)
            }
    
            function n(e, t) {
                return "number" != typeof t && (t = 0), setTimeout(e, t)
            }
    
            function r(e, t) {
                return "number" != typeof t && (t = 0), setInterval(e, t)
            }
    
            function i(e) {
                return clearTimeout(e)
            }
    
            function o(e) {
                return clearInterval(e)
            }
            var a;
            return {
                requestAnimationFrame: function(n, r) {
                    return a ? void a.then(n) : void(a = new e(function(e) {
                        r || (r = document.body), t(e, r)
                    }).then(n))
                },
                setTimeout: n,
                setInterval: r,
                setEditorTimeout: function(e, t, r) {
                    return n(function() {
                        e.removed || t()
                    }, r)
                },
                setEditorInterval: function(e, t, n) {
                    var i;
                    return i = r(function() {
                        e.removed ? clearInterval(i) : t()
                    }, n)
                },
                throttle: function(e, t) {
                    var r;
                    return function() {
                        var i = arguments;
                        clearTimeout(r), r = n(function() {
                            e.apply(this, i)
                        }, t)
                    }
                },
                clearInterval: o,
                clearTimeout: i
            }
        }), r(d, [u], function(e) {
            function t(e, t, n, r) {
                e.addEventListener ? e.addEventListener(t, n, r || !1) : e.attachEvent && e.attachEvent("on" + t, n)
            }
    
            function n(e, t, n, r) {
                e.removeEventListener ? e.removeEventListener(t, n, r || !1) : e.detachEvent && e.detachEvent("on" + t, n)
            }
    
            function r(e, t) {
                function n() {
                    return !1
                }
    
                function r() {
                    return !0
                }
                var i, o = t || {},
                    a;
                for (i in e) l[i] || (o[i] = e[i]);
                if (o.target || (o.target = o.srcElement || document), e && s.test(e.type) && e.pageX === a && e.clientX !== a) {
                    var c = o.target.ownerDocument || document,
                        u = c.documentElement,
                        d = c.body;
                    o.pageX = e.clientX + (u && u.scrollLeft || d && d.scrollLeft || 0) - (u && u.clientLeft || d && d.clientLeft || 0), o.pageY = e.clientY + (u && u.scrollTop || d && d.scrollTop || 0) - (u && u.clientTop || d && d.clientTop || 0)
                }
                return o.preventDefault = function() {
                    o.isDefaultPrevented = r, e && (e.preventDefault ? e.preventDefault() : e.returnValue = !1)
                }, o.stopPropagation = function() {
                    o.isPropagationStopped = r, e && (e.stopPropagation ? e.stopPropagation() : e.cancelBubble = !0)
                }, o.stopImmediatePropagation = function() {
                    o.isImmediatePropagationStopped = r, o.stopPropagation()
                }, o.isDefaultPrevented || (o.isDefaultPrevented = n, o.isPropagationStopped = n, o.isImmediatePropagationStopped = n), "undefined" == typeof o.metaKey && (o.metaKey = !1), o
            }
    
            function i(r, i, o) {
                function a() {
                    o.domLoaded || (o.domLoaded = !0, i(u))
                }
    
                function s() {
                    ("complete" === c.readyState || "interactive" === c.readyState && c.body) && (n(c, "readystatechange", s), a())
                }
    
                function l() {
                    try {
                        c.documentElement.doScroll("left")
                    } catch (t) {
                        return void e.setTimeout(l)
                    }
                    a()
                }
                var c = r.document,
                    u = {
                        type: "ready"
                    };
                return o.domLoaded ? void i(u) : (c.addEventListener ? "complete" === c.readyState ? a() : t(r, "DOMContentLoaded", a) : (t(c, "readystatechange", s), c.documentElement.doScroll && r.self === r.top && l()), void t(r, "load", a))
            }
    
            function o() {
                function e(e, t) {
                    var n, r, i, o, a = s[t];
                    if (n = a && a[e.type])
                        for (r = 0, i = n.length; i > r; r++)
                            if (o = n[r], o && o.func.call(o.scope, e) === !1 && e.preventDefault(), e.isImmediatePropagationStopped()) return
                }
                var o = this,
                    s = {},
                    l, c, u, d, f;
                c = a + (+new Date).toString(32), d = "onmouseenter" in document.documentElement, u = "onfocusin" in document.documentElement, f = {
                    mouseenter: "mouseover",
                    mouseleave: "mouseout"
                }, l = 1, o.domLoaded = !1, o.events = s, o.bind = function(n, a, h, p) {
                    function m(t) {
                        e(r(t || E.event), g)
                    }
                    var g, v, y, b, C, x, w, E = window;
                    if (n && 3 !== n.nodeType && 8 !== n.nodeType) {
                        for (n[c] ? g = n[c] : (g = l++, n[c] = g, s[g] = {}), p = p || n, a = a.split(" "), y = a.length; y--;) b = a[y], x = m, C = w = !1, "DOMContentLoaded" === b && (b = "ready"), o.domLoaded && "ready" === b && "complete" == n.readyState ? h.call(p, r({
                            type: b
                        })) : (d || (C = f[b], C && (x = function(t) {
                            var n, i;
                            if (n = t.currentTarget, i = t.relatedTarget, i && n.contains) i = n.contains(i);
                            else
                                for (; i && i !== n;) i = i.parentNode;
                            i || (t = r(t || E.event), t.type = "mouseout" === t.type ? "mouseleave" : "mouseenter", t.target = n, e(t, g))
                        })), u || "focusin" !== b && "focusout" !== b || (w = !0, C = "focusin" === b ? "focus" : "blur", x = function(t) {
                            t = r(t || E.event), t.type = "focus" === t.type ? "focusin" : "focusout", e(t, g)
                        }), v = s[g][b], v ? "ready" === b && o.domLoaded ? h({
                            type: b
                        }) : v.push({
                            func: h,
                            scope: p
                        }) : (s[g][b] = v = [{
                            func: h,
                            scope: p
                        }], v.fakeName = C, v.capture = w, v.nativeHandler = x, "ready" === b ? i(n, x, o) : t(n, C || b, x, w)));
                        return n = v = 0, h
                    }
                }, o.unbind = function(e, t, r) {
                    var i, a, l, u, d, f;
                    if (!e || 3 === e.nodeType || 8 === e.nodeType) return o;
                    if (i = e[c]) {
                        if (f = s[i], t) {
                            for (t = t.split(" "), l = t.length; l--;)
                                if (d = t[l], a = f[d]) {
                                    if (r)
                                        for (u = a.length; u--;)
                                            if (a[u].func === r) {
                                                var h = a.nativeHandler,
                                                    p = a.fakeName,
                                                    m = a.capture;
                                                a = a.slice(0, u).concat(a.slice(u + 1)), a.nativeHandler = h, a.fakeName = p, a.capture = m, f[d] = a
                                            }
                                    r && 0 !== a.length || (delete f[d], n(e, a.fakeName || d, a.nativeHandler, a.capture))
                                }
                        } else {
                            for (d in f) a = f[d], n(e, a.fakeName || d, a.nativeHandler, a.capture);
                            f = {}
                        }
                        for (d in f) return o;
                        delete s[i];
                        try {
                            delete e[c]
                        } catch (g) {
                            e[c] = null
                        }
                    }
                    return o
                }, o.fire = function(t, n, i) {
                    var a;
                    if (!t || 3 === t.nodeType || 8 === t.nodeType) return o;
                    i = r(null, i), i.type = n, i.target = t;
                    do a = t[c], a && e(i, a), t = t.parentNode || t.ownerDocument || t.defaultView || t.parentWindow; while (t && !i.isPropagationStopped());
                    return o
                }, o.clean = function(e) {
                    var t, n, r = o.unbind;
                    if (!e || 3 === e.nodeType || 8 === e.nodeType) return o;
                    if (e[c] && r(e), e.getElementsByTagName || (e = e.document), e && e.getElementsByTagName)
                        for (r(e), n = e.getElementsByTagName("*"), t = n.length; t--;) e = n[t], e[c] && r(e);
                    return o
                }, o.destroy = function() {
                    s = {}
                }, o.cancel = function(e) {
                    return e && (e.preventDefault(), e.stopImmediatePropagation()), !1
                }
            }
            var a = "mce-data-",
                s = /^(?:mouse|contextmenu)|click/,
                l = {
                    keyLocation: 1,
                    layerX: 1,
                    layerY: 1,
                    returnValue: 1,
                    webkitMovementX: 1,
                    webkitMovementY: 1
                };
            return o.Event = new o, o.Event.bind(window, "ready", function() {}), o
        }), r(f, [], function() {
            function e(e, t, n, r) {
                var i, o, a, s, l, c, d, h, p, m;
                if ((t ? t.ownerDocument || t : z) !== D && B(t), t = t || D, n = n || [], !e || "string" != typeof e) return n;
                if (1 !== (s = t.nodeType) && 9 !== s) return [];
                if (L && !r) {
                    if (i = ve.exec(e))
                        if (a = i[1]) {
                            if (9 === s) {
                                if (o = t.getElementById(a), !o || !o.parentNode) return n;
                                if (o.id === a) return n.push(o), n
                            } else if (t.ownerDocument && (o = t.ownerDocument.getElementById(a)) && I(t, o) && o.id === a) return n.push(o), n
                        } else {
                            if (i[2]) return Z.apply(n, t.getElementsByTagName(e)), n;
                            if ((a = i[3]) && x.getElementsByClassName) return Z.apply(n, t.getElementsByClassName(a)), n
                        }
                    if (x.qsa && (!P || !P.test(e))) {
                        if (h = d = F, p = t, m = 9 === s && e, 1 === s && "object" !== t.nodeName.toLowerCase()) {
                            for (c = _(e), (d = t.getAttribute("id")) ? h = d.replace(be, "\\$&") : t.setAttribute("id", h), h = "[id='" + h + "'] ", l = c.length; l--;) c[l] = h + f(c[l]);
                            p = ye.test(e) && u(t.parentNode) || t, m = c.join(",")
                        }
                        if (m) try {
                            return Z.apply(n, p.querySelectorAll(m)), n
                        } catch (g) {} finally {
                            d || t.removeAttribute("id")
                        }
                    }
                }
                return k(e.replace(se, "$1"), t, n, r)
            }
    
            function n() {
                function e(n, r) {
                    return t.push(n + " ") > w.cacheLength && delete e[t.shift()], e[n + " "] = r
                }
                var t = [];
                return e
            }
    
            function r(e) {
                return e[F] = !0, e
            }
    
            function i(e) {
                var t = D.createElement("div");
                try {
                    return !!e(t)
                } catch (n) {
                    return !1
                } finally {
                    t.parentNode && t.parentNode.removeChild(t), t = null
                }
            }
    
            function o(e, t) {
                for (var n = e.split("|"), r = e.length; r--;) w.attrHandle[n[r]] = t
            }
    
            function a(e, t) {
                var n = t && e,
                    r = n && 1 === e.nodeType && 1 === t.nodeType && (~t.sourceIndex || X) - (~e.sourceIndex || X);
                if (r) return r;
                if (n)
                    for (; n = n.nextSibling;)
                        if (n === t) return -1;
                return e ? 1 : -1
            }
    
            function s(e) {
                return function(t) {
                    var n = t.nodeName.toLowerCase();
                    return "input" === n && t.type === e
                }
            }
    
            function l(e) {
                return function(t) {
                    var n = t.nodeName.toLowerCase();
                    return ("input" === n || "button" === n) && t.type === e
                }
            }
    
            function c(e) {
                return r(function(t) {
                    return t = +t, r(function(n, r) {
                        for (var i, o = e([], n.length, t), a = o.length; a--;) n[i = o[a]] && (n[i] = !(r[i] = n[i]))
                    })
                })
            }
    
            function u(e) {
                return e && typeof e.getElementsByTagName !== Y && e
            }
    
            function d() {}
    
            function f(e) {
                for (var t = 0, n = e.length, r = ""; n > t; t++) r += e[t].value;
                return r
            }
    
            function h(e, t, n) {
                var r = t.dir,
                    i = n && "parentNode" === r,
                    o = V++;
                return t.first ? function(t, n, o) {
                    for (; t = t[r];)
                        if (1 === t.nodeType || i) return e(t, n, o)
                } : function(t, n, a) {
                    var s, l, c = [W, o];
                    if (a) {
                        for (; t = t[r];)
                            if ((1 === t.nodeType || i) && e(t, n, a)) return !0
                    } else
                        for (; t = t[r];)
                            if (1 === t.nodeType || i) {
                                if (l = t[F] || (t[F] = {}), (s = l[r]) && s[0] === W && s[1] === o) return c[2] = s[2];
                                if (l[r] = c, c[2] = e(t, n, a)) return !0
                            }
                }
            }
    
            function p(e) {
                return e.length > 1 ? function(t, n, r) {
                    for (var i = e.length; i--;)
                        if (!e[i](t, n, r)) return !1;
                    return !0
                } : e[0]
            }
    
            function m(t, n, r) {
                for (var i = 0, o = n.length; o > i; i++) e(t, n[i], r);
                return r
            }
    
            function g(e, t, n, r, i) {
                for (var o, a = [], s = 0, l = e.length, c = null != t; l > s; s++)(o = e[s]) && (!n || n(o, r, i)) && (a.push(o), c && t.push(s));
                return a
            }
    
            function v(e, t, n, i, o, a) {
                return i && !i[F] && (i = v(i)), o && !o[F] && (o = v(o, a)), r(function(r, a, s, l) {
                    var c, u, d, f = [],
                        h = [],
                        p = a.length,
                        v = r || m(t || "*", s.nodeType ? [s] : s, []),
                        y = !e || !r && t ? v : g(v, f, e, s, l),
                        b = n ? o || (r ? e : p || i) ? [] : a : y;
                    if (n && n(y, b, s, l), i)
                        for (c = g(b, h), i(c, [], s, l), u = c.length; u--;)(d = c[u]) && (b[h[u]] = !(y[h[u]] = d));
                    if (r) {
                        if (o || e) {
                            if (o) {
                                for (c = [], u = b.length; u--;)(d = b[u]) && c.push(y[u] = d);
                                o(null, b = [], c, l)
                            }
                            for (u = b.length; u--;)(d = b[u]) && (c = o ? te.call(r, d) : f[u]) > -1 && (r[c] = !(a[c] = d))
                        }
                    } else b = g(b === a ? b.splice(p, b.length) : b), o ? o(null, a, b, l) : Z.apply(a, b)
                })
            }
    
            function y(e) {
                for (var t, n, r, i = e.length, o = w.relative[e[0].type], a = o || w.relative[" "], s = o ? 1 : 0, l = h(function(e) {
                        return e === t
                    }, a, !0), c = h(function(e) {
                        return te.call(t, e) > -1
                    }, a, !0), u = [function(e, n, r) {
                        return !o && (r || n !== T) || ((t = n).nodeType ? l(e, n, r) : c(e, n, r))
                    }]; i > s; s++)
                    if (n = w.relative[e[s].type]) u = [h(p(u), n)];
                    else {
                        if (n = w.filter[e[s].type].apply(null, e[s].matches), n[F]) {
                            for (r = ++s; i > r && !w.relative[e[r].type]; r++);
                            return v(s > 1 && p(u), s > 1 && f(e.slice(0, s - 1).concat({
                                value: " " === e[s - 2].type ? "*" : ""
                            })).replace(se, "$1"), n, r > s && y(e.slice(s, r)), i > r && y(e = e.slice(r)), i > r && f(e))
                        }
                        u.push(n)
                    }
                return p(u)
            }
    
            function b(t, n) {
                var i = n.length > 0,
                    o = t.length > 0,
                    a = function(r, a, s, l, c) {
                        var u, d, f, h = 0,
                            p = "0",
                            m = r && [],
                            v = [],
                            y = T,
                            b = r || o && w.find.TAG("*", c),
                            C = W += null == y ? 1 : Math.random() || .1,
                            x = b.length;
                        for (c && (T = a !== D && a); p !== x && null != (u = b[p]); p++) {
                            if (o && u) {
                                for (d = 0; f = t[d++];)
                                    if (f(u, a, s)) {
                                        l.push(u);
                                        break
                                    }
                                c && (W = C)
                            }
                            i && ((u = !f && u) && h--, r && m.push(u))
                        }
                        if (h += p, i && p !== h) {
                            for (d = 0; f = n[d++];) f(m, v, a, s);
                            if (r) {
                                if (h > 0)
                                    for (; p--;) m[p] || v[p] || (v[p] = J.call(l));
                                v = g(v)
                            }
                            Z.apply(l, v), c && !r && v.length > 0 && h + n.length > 1 && e.uniqueSort(l)
                        }
                        return c && (W = C, T = y), m
                    };
                return i ? r(a) : a
            }
            var C, x, w, E, N, _, S, k, T, R, A, B, D, M, L, P, H, O, I, F = "sizzle" + -new Date,
                z = window.document,
                W = 0,
                V = 0,
                U = n(),
                $ = n(),
                q = n(),
                j = function(e, t) {
                    return e === t && (A = !0), 0
                },
                Y = typeof t,
                X = 1 << 31,
                K = {}.hasOwnProperty,
                G = [],
                J = G.pop,
                Q = G.push,
                Z = G.push,
                ee = G.slice,
                te = G.indexOf || function(e) {
                    for (var t = 0, n = this.length; n > t; t++)
                        if (this[t] === e) return t;
                    return -1
                },
                ne = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
                re = "[\\x20\\t\\r\\n\\f]",
                ie = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
                oe = "\\[" + re + "*(" + ie + ")(?:" + re + "*([*^$|!~]?=)" + re + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + ie + "))|)" + re + "*\\]",
                ae = ":(" + ie + ")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|" + oe + ")*)|.*)\\)|)",
                se = new RegExp("^" + re + "+|((?:^|[^\\\\])(?:\\\\.)*)" + re + "+$", "g"),
                le = new RegExp("^" + re + "*," + re + "*"),
                ce = new RegExp("^" + re + "*([>+~]|" + re + ")" + re + "*"),
                ue = new RegExp("=" + re + "*([^\\]'\"]*?)" + re + "*\\]", "g"),
                de = new RegExp(ae),
                fe = new RegExp("^" + ie + "$"),
                he = {
                    ID: new RegExp("^#(" + ie + ")"),
                    CLASS: new RegExp("^\\.(" + ie + ")"),
                    TAG: new RegExp("^(" + ie + "|[*])"),
                    ATTR: new RegExp("^" + oe),
                    PSEUDO: new RegExp("^" + ae),
                    CHILD: new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + re + "*(even|odd|(([+-]|)(\\d*)n|)" + re + "*(?:([+-]|)" + re + "*(\\d+)|))" + re + "*\\)|)", "i"),
                    bool: new RegExp("^(?:" + ne + ")$", "i"),
                    needsContext: new RegExp("^" + re + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + re + "*((?:-\\d)?\\d*)" + re + "*\\)|)(?=[^-]|$)", "i")
                },
                pe = /^(?:input|select|textarea|button)$/i,
                me = /^h\d$/i,
                ge = /^[^{]+\{\s*\[native \w/,
                ve = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
                ye = /[+~]/,
                be = /'|\\/g,
                Ce = new RegExp("\\\\([\\da-f]{1,6}" + re + "?|(" + re + ")|.)", "ig"),
                xe = function(e, t, n) {
                    var r = "0x" + t - 65536;
                    return r !== r || n ? t : 0 > r ? String.fromCharCode(r + 65536) : String.fromCharCode(r >> 10 | 55296, 1023 & r | 56320)
                };
            try {
                Z.apply(G = ee.call(z.childNodes), z.childNodes), G[z.childNodes.length].nodeType
            } catch (we) {
                Z = {
                    apply: G.length ? function(e, t) {
                        Q.apply(e, ee.call(t))
                    } : function(e, t) {
                        for (var n = e.length, r = 0; e[n++] = t[r++];);
                        e.length = n - 1
                    }
                }
            }
            x = e.support = {}, N = e.isXML = function(e) {
                var t = e && (e.ownerDocument || e).documentElement;
                return t ? "HTML" !== t.nodeName : !1
            }, B = e.setDocument = function(e) {
                var t, n = e ? e.ownerDocument || e : z,
                    r = n.defaultView;
                return n !== D && 9 === n.nodeType && n.documentElement ? (D = n, M = n.documentElement, L = !N(n), r && r !== r.top && (r.addEventListener ? r.addEventListener("unload", function() {
                    B()
                }, !1) : r.attachEvent && r.attachEvent("onunload", function() {
                    B()
                })), x.attributes = i(function(e) {
                    return e.className = "i", !e.getAttribute("className")
                }), x.getElementsByTagName = i(function(e) {
                    return e.appendChild(n.createComment("")), !e.getElementsByTagName("*").length
                }), x.getElementsByClassName = ge.test(n.getElementsByClassName), x.getById = i(function(e) {
                    return M.appendChild(e).id = F, !n.getElementsByName || !n.getElementsByName(F).length
                }), x.getById ? (w.find.ID = function(e, t) {
                    if (typeof t.getElementById !== Y && L) {
                        var n = t.getElementById(e);
                        return n && n.parentNode ? [n] : []
                    }
                }, w.filter.ID = function(e) {
                    var t = e.replace(Ce, xe);
                    return function(e) {
                        return e.getAttribute("id") === t
                    }
                }) : (delete w.find.ID, w.filter.ID = function(e) {
                    var t = e.replace(Ce, xe);
                    return function(e) {
                        var n = typeof e.getAttributeNode !== Y && e.getAttributeNode("id");
                        return n && n.value === t
                    }
                }), w.find.TAG = x.getElementsByTagName ? function(e, t) {
                    return typeof t.getElementsByTagName !== Y ? t.getElementsByTagName(e) : void 0
                } : function(e, t) {
                    var n, r = [],
                        i = 0,
                        o = t.getElementsByTagName(e);
                    if ("*" === e) {
                        for (; n = o[i++];) 1 === n.nodeType && r.push(n);
                        return r
                    }
                    return o
                }, w.find.CLASS = x.getElementsByClassName && function(e, t) {
                    return L ? t.getElementsByClassName(e) : void 0
                }, H = [], P = [], (x.qsa = ge.test(n.querySelectorAll)) && (i(function(e) {
                    e.innerHTML = "<select msallowcapture=''><option selected=''></option></select>", e.querySelectorAll("[msallowcapture^='']").length && P.push("[*^$]=" + re + "*(?:''|\"\")"), e.querySelectorAll("[selected]").length || P.push("\\[" + re + "*(?:value|" + ne + ")"), e.querySelectorAll(":checked").length || P.push(":checked")
                }), i(function(e) {
                    var t = n.createElement("input");
                    t.setAttribute("type", "hidden"), e.appendChild(t).setAttribute("name", "D"), e.querySelectorAll("[name=d]").length && P.push("name" + re + "*[*^$|!~]?="), e.querySelectorAll(":enabled").length || P.push(":enabled", ":disabled"), e.querySelectorAll("*,:x"), P.push(",.*:")
                })), (x.matchesSelector = ge.test(O = M.matches || M.webkitMatchesSelector || M.mozMatchesSelector || M.oMatchesSelector || M.msMatchesSelector)) && i(function(e) {
                    x.disconnectedMatch = O.call(e, "div"), O.call(e, "[s!='']:x"), H.push("!=", ae)
                }), P = P.length && new RegExp(P.join("|")), H = H.length && new RegExp(H.join("|")), t = ge.test(M.compareDocumentPosition), I = t || ge.test(M.contains) ? function(e, t) {
                    var n = 9 === e.nodeType ? e.documentElement : e,
                        r = t && t.parentNode;
                    return e === r || !(!r || 1 !== r.nodeType || !(n.contains ? n.contains(r) : e.compareDocumentPosition && 16 & e.compareDocumentPosition(r)))
                } : function(e, t) {
                    if (t)
                        for (; t = t.parentNode;)
                            if (t === e) return !0;
                    return !1
                }, j = t ? function(e, t) {
                    if (e === t) return A = !0, 0;
                    var r = !e.compareDocumentPosition - !t.compareDocumentPosition;
                    return r ? r : (r = (e.ownerDocument || e) === (t.ownerDocument || t) ? e.compareDocumentPosition(t) : 1, 1 & r || !x.sortDetached && t.compareDocumentPosition(e) === r ? e === n || e.ownerDocument === z && I(z, e) ? -1 : t === n || t.ownerDocument === z && I(z, t) ? 1 : R ? te.call(R, e) - te.call(R, t) : 0 : 4 & r ? -1 : 1)
                } : function(e, t) {
                    if (e === t) return A = !0, 0;
                    var r, i = 0,
                        o = e.parentNode,
                        s = t.parentNode,
                        l = [e],
                        c = [t];
                    if (!o || !s) return e === n ? -1 : t === n ? 1 : o ? -1 : s ? 1 : R ? te.call(R, e) - te.call(R, t) : 0;
                    if (o === s) return a(e, t);
                    for (r = e; r = r.parentNode;) l.unshift(r);
                    for (r = t; r = r.parentNode;) c.unshift(r);
                    for (; l[i] === c[i];) i++;
                    return i ? a(l[i], c[i]) : l[i] === z ? -1 : c[i] === z ? 1 : 0
                }, n) : D
            }, e.matches = function(t, n) {
                return e(t, null, null, n)
            }, e.matchesSelector = function(t, n) {
                if ((t.ownerDocument || t) !== D && B(t), n = n.replace(ue, "='$1']"), x.matchesSelector && L && (!H || !H.test(n)) && (!P || !P.test(n))) try {
                    var r = O.call(t, n);
                    if (r || x.disconnectedMatch || t.document && 11 !== t.document.nodeType) return r
                } catch (i) {}
                return e(n, D, null, [t]).length > 0
            }, e.contains = function(e, t) {
                return (e.ownerDocument || e) !== D && B(e), I(e, t)
            }, e.attr = function(e, n) {
                (e.ownerDocument || e) !== D && B(e);
                var r = w.attrHandle[n.toLowerCase()],
                    i = r && K.call(w.attrHandle, n.toLowerCase()) ? r(e, n, !L) : t;
                return i !== t ? i : x.attributes || !L ? e.getAttribute(n) : (i = e.getAttributeNode(n)) && i.specified ? i.value : null
            }, e.error = function(e) {
                throw new Error("Syntax error, unrecognized expression: " + e)
            }, e.uniqueSort = function(e) {
                var t, n = [],
                    r = 0,
                    i = 0;
                if (A = !x.detectDuplicates, R = !x.sortStable && e.slice(0), e.sort(j), A) {
                    for (; t = e[i++];) t === e[i] && (r = n.push(i));
                    for (; r--;) e.splice(n[r], 1)
                }
                return R = null, e
            }, E = e.getText = function(e) {
                var t, n = "",
                    r = 0,
                    i = e.nodeType;
                if (i) {
                    if (1 === i || 9 === i || 11 === i) {
                        if ("string" == typeof e.textContent) return e.textContent;
                        for (e = e.firstChild; e; e = e.nextSibling) n += E(e)
                    } else if (3 === i || 4 === i) return e.nodeValue
                } else
                    for (; t = e[r++];) n += E(t);
                return n
            }, w = e.selectors = {
                cacheLength: 50,
                createPseudo: r,
                match: he,
                attrHandle: {},
                find: {},
                relative: {
                    ">": {
                        dir: "parentNode",
                        first: !0
                    },
                    " ": {
                        dir: "parentNode"
                    },
                    "+": {
                        dir: "previousSibling",
                        first: !0
                    },
                    "~": {
                        dir: "previousSibling"
                    }
                },
                preFilter: {
                    ATTR: function(e) {
                        return e[1] = e[1].replace(Ce, xe), e[3] = (e[3] || e[4] || e[5] || "").replace(Ce, xe), "~=" === e[2] && (e[3] = " " + e[3] + " "), e.slice(0, 4)
                    },
                    CHILD: function(t) {
                        return t[1] = t[1].toLowerCase(), "nth" === t[1].slice(0, 3) ? (t[3] || e.error(t[0]), t[4] = +(t[4] ? t[5] + (t[6] || 1) : 2 * ("even" === t[3] || "odd" === t[3])), t[5] = +(t[7] + t[8] || "odd" === t[3])) : t[3] && e.error(t[0]), t
                    },
                    PSEUDO: function(e) {
                        var t, n = !e[6] && e[2];
                        return he.CHILD.test(e[0]) ? null : (e[3] ? e[2] = e[4] || e[5] || "" : n && de.test(n) && (t = _(n, !0)) && (t = n.indexOf(")", n.length - t) - n.length) && (e[0] = e[0].slice(0, t), e[2] = n.slice(0, t)), e.slice(0, 3))
                    }
                },
                filter: {
                    TAG: function(e) {
                        var t = e.replace(Ce, xe).toLowerCase();
                        return "*" === e ? function() {
                            return !0
                        } : function(e) {
                            return e.nodeName && e.nodeName.toLowerCase() === t
                        }
                    },
                    CLASS: function(e) {
                        var t = U[e + " "];
                        return t || (t = new RegExp("(^|" + re + ")" + e + "(" + re + "|$)")) && U(e, function(e) {
                            return t.test("string" == typeof e.className && e.className || typeof e.getAttribute !== Y && e.getAttribute("class") || "")
                        })
                    },
                    ATTR: function(t, n, r) {
                        return function(i) {
                            var o = e.attr(i, t);
                            return null == o ? "!=" === n : n ? (o += "", "=" === n ? o === r : "!=" === n ? o !== r : "^=" === n ? r && 0 === o.indexOf(r) : "*=" === n ? r && o.indexOf(r) > -1 : "$=" === n ? r && o.slice(-r.length) === r : "~=" === n ? (" " + o + " ").indexOf(r) > -1 : "|=" === n ? o === r || o.slice(0, r.length + 1) === r + "-" : !1) : !0
                        }
                    },
                    CHILD: function(e, t, n, r, i) {
                        var o = "nth" !== e.slice(0, 3),
                            a = "last" !== e.slice(-4),
                            s = "of-type" === t;
                        return 1 === r && 0 === i ? function(e) {
                            return !!e.parentNode
                        } : function(t, n, l) {
                            var c, u, d, f, h, p, m = o !== a ? "nextSibling" : "previousSibling",
                                g = t.parentNode,
                                v = s && t.nodeName.toLowerCase(),
                                y = !l && !s;
                            if (g) {
                                if (o) {
                                    for (; m;) {
                                        for (d = t; d = d[m];)
                                            if (s ? d.nodeName.toLowerCase() === v : 1 === d.nodeType) return !1;
                                        p = m = "only" === e && !p && "nextSibling"
                                    }
                                    return !0
                                }
                                if (p = [a ? g.firstChild : g.lastChild], a && y) {
                                    for (u = g[F] || (g[F] = {}), c = u[e] || [], h = c[0] === W && c[1], f = c[0] === W && c[2], d = h && g.childNodes[h]; d = ++h && d && d[m] || (f = h = 0) || p.pop();)
                                        if (1 === d.nodeType && ++f && d === t) {
                                            u[e] = [W, h, f];
                                            break
                                        }
                                } else if (y && (c = (t[F] || (t[F] = {}))[e]) && c[0] === W) f = c[1];
                                else
                                    for (;
                                        (d = ++h && d && d[m] || (f = h = 0) || p.pop()) && ((s ? d.nodeName.toLowerCase() !== v : 1 !== d.nodeType) || !++f || (y && ((d[F] || (d[F] = {}))[e] = [W, f]), d !== t)););
                                return f -= i, f === r || f % r === 0 && f / r >= 0
                            }
                        }
                    },
                    PSEUDO: function(t, n) {
                        var i, o = w.pseudos[t] || w.setFilters[t.toLowerCase()] || e.error("unsupported pseudo: " + t);
                        return o[F] ? o(n) : o.length > 1 ? (i = [t, t, "", n], w.setFilters.hasOwnProperty(t.toLowerCase()) ? r(function(e, t) {
                            for (var r, i = o(e, n), a = i.length; a--;) r = te.call(e, i[a]), e[r] = !(t[r] = i[a])
                        }) : function(e) {
                            return o(e, 0, i)
                        }) : o
                    }
                },
                pseudos: {
                    not: r(function(e) {
                        var t = [],
                            n = [],
                            i = S(e.replace(se, "$1"));
                        return i[F] ? r(function(e, t, n, r) {
                            for (var o, a = i(e, null, r, []), s = e.length; s--;)(o = a[s]) && (e[s] = !(t[s] = o))
                        }) : function(e, r, o) {
                            return t[0] = e, i(t, null, o, n), !n.pop()
                        }
                    }),
                    has: r(function(t) {
                        return function(n) {
                            return e(t, n).length > 0
                        }
                    }),
                    contains: r(function(e) {
                        return e = e.replace(Ce, xe),
                            function(t) {
                                return (t.textContent || t.innerText || E(t)).indexOf(e) > -1
                            }
                    }),
                    lang: r(function(t) {
                        return fe.test(t || "") || e.error("unsupported lang: " + t), t = t.replace(Ce, xe).toLowerCase(),
                            function(e) {
                                var n;
                                do
                                    if (n = L ? e.lang : e.getAttribute("xml:lang") || e.getAttribute("lang")) return n = n.toLowerCase(), n === t || 0 === n.indexOf(t + "-"); while ((e = e.parentNode) && 1 === e.nodeType);
                                return !1
                            }
                    }),
                    target: function(e) {
                        var t = window.location && window.location.hash;
                        return t && t.slice(1) === e.id
                    },
                    root: function(e) {
                        return e === M
                    },
                    focus: function(e) {
                        return e === D.activeElement && (!D.hasFocus || D.hasFocus()) && !!(e.type || e.href || ~e.tabIndex)
                    },
                    enabled: function(e) {
                        return e.disabled === !1
                    },
                    disabled: function(e) {
                        return e.disabled === !0
                    },
                    checked: function(e) {
                        var t = e.nodeName.toLowerCase();
                        return "input" === t && !!e.checked || "option" === t && !!e.selected
                    },
                    selected: function(e) {
                        return e.parentNode && e.parentNode.selectedIndex, e.selected === !0
                    },
                    empty: function(e) {
                        for (e = e.firstChild; e; e = e.nextSibling)
                            if (e.nodeType < 6) return !1;
                        return !0
                    },
                    parent: function(e) {
                        return !w.pseudos.empty(e)
                    },
                    header: function(e) {
                        return me.test(e.nodeName)
                    },
                    input: function(e) {
                        return pe.test(e.nodeName)
                    },
                    button: function(e) {
                        var t = e.nodeName.toLowerCase();
                        return "input" === t && "button" === e.type || "button" === t
                    },
                    text: function(e) {
                        var t;
                        return "input" === e.nodeName.toLowerCase() && "text" === e.type && (null == (t = e.getAttribute("type")) || "text" === t.toLowerCase())
                    },
                    first: c(function() {
                        return [0]
                    }),
                    last: c(function(e, t) {
                        return [t - 1]
                    }),
                    eq: c(function(e, t, n) {
                        return [0 > n ? n + t : n]
                    }),
                    even: c(function(e, t) {
                        for (var n = 0; t > n; n += 2) e.push(n);
                        return e
                    }),
                    odd: c(function(e, t) {
                        for (var n = 1; t > n; n += 2) e.push(n);
                        return e
                    }),
                    lt: c(function(e, t, n) {
                        for (var r = 0 > n ? n + t : n; --r >= 0;) e.push(r);
                        return e
                    }),
                    gt: c(function(e, t, n) {
                        for (var r = 0 > n ? n + t : n; ++r < t;) e.push(r);
                        return e
                    })
                }
            }, w.pseudos.nth = w.pseudos.eq;
            for (C in {
                    radio: !0,
                    checkbox: !0,
                    file: !0,
                    password: !0,
                    image: !0
                }) w.pseudos[C] = s(C);
            for (C in {
                    submit: !0,
                    reset: !0
                }) w.pseudos[C] = l(C);
            return d.prototype = w.filters = w.pseudos, w.setFilters = new d, _ = e.tokenize = function(t, n) {
                var r, i, o, a, s, l, c, u = $[t + " "];
                if (u) return n ? 0 : u.slice(0);
                for (s = t, l = [], c = w.preFilter; s;) {
                    (!r || (i = le.exec(s))) && (i && (s = s.slice(i[0].length) || s), l.push(o = [])), r = !1, (i = ce.exec(s)) && (r = i.shift(), o.push({
                        value: r,
                        type: i[0].replace(se, " ")
                    }), s = s.slice(r.length));
                    for (a in w.filter) !(i = he[a].exec(s)) || c[a] && !(i = c[a](i)) || (r = i.shift(), o.push({
                        value: r,
                        type: a,
                        matches: i
                    }), s = s.slice(r.length));
                    if (!r) break
                }
                return n ? s.length : s ? e.error(t) : $(t, l).slice(0)
            }, S = e.compile = function(e, t) {
                var n, r = [],
                    i = [],
                    o = q[e + " "];
                if (!o) {
                    for (t || (t = _(e)), n = t.length; n--;) o = y(t[n]), o[F] ? r.push(o) : i.push(o);
                    o = q(e, b(i, r)), o.selector = e
                }
                return o
            }, k = e.select = function(e, t, n, r) {
                var i, o, a, s, l, c = "function" == typeof e && e,
                    d = !r && _(e = c.selector || e);
                if (n = n || [], 1 === d.length) {
                    if (o = d[0] = d[0].slice(0), o.length > 2 && "ID" === (a = o[0]).type && x.getById && 9 === t.nodeType && L && w.relative[o[1].type]) {
                        if (t = (w.find.ID(a.matches[0].replace(Ce, xe), t) || [])[0], !t) return n;
                        c && (t = t.parentNode), e = e.slice(o.shift().value.length)
                    }
                    for (i = he.needsContext.test(e) ? 0 : o.length; i-- && (a = o[i], !w.relative[s = a.type]);)
                        if ((l = w.find[s]) && (r = l(a.matches[0].replace(Ce, xe), ye.test(o[0].type) && u(t.parentNode) || t))) {
                            if (o.splice(i, 1), e = r.length && f(o), !e) return Z.apply(n, r), n;
                            break
                        }
                }
                return (c || S(e, d))(r, t, !L, n, ye.test(e) && u(t.parentNode) || t), n
            }, x.sortStable = F.split("").sort(j).join("") === F, x.detectDuplicates = !!A, B(), x.sortDetached = i(function(e) {
                return 1 & e.compareDocumentPosition(D.createElement("div"))
            }), i(function(e) {
                return e.innerHTML = "<a href='#'></a>", "#" === e.firstChild.getAttribute("href")
            }) || o("type|href|height|width", function(e, t, n) {
                return n ? void 0 : e.getAttribute(t, "type" === t.toLowerCase() ? 1 : 2)
            }), x.attributes && i(function(e) {
                return e.innerHTML = "<input/>", e.firstChild.setAttribute("value", ""), "" === e.firstChild.getAttribute("value")
            }) || o("value", function(e, t, n) {
                return n || "input" !== e.nodeName.toLowerCase() ? void 0 : e.defaultValue
            }), i(function(e) {
                return null == e.getAttribute("disabled")
            }) || o(ne, function(e, t, n) {
                var r;
                return n ? void 0 : e[t] === !0 ? t.toLowerCase() : (r = e.getAttributeNode(t)) && r.specified ? r.value : null
            }), e
        }), r(h, [], function() {
            function e(e) {
                return "matchMedia" in window ? matchMedia(e).matches : !1
            }
            var t = navigator,
                n = t.userAgent,
                r, i, o, a, s, l, c, u, d, f, h, p;
            r = window.opera && window.opera.buildNumber, d = /Android/.test(n), i = /WebKit/.test(n), o = !i && !r && /MSIE/gi.test(n) && /Explorer/gi.test(t.appName), o = o && /MSIE (\w+)\./.exec(n)[1], a = -1 == n.indexOf("Trident/") || -1 == n.indexOf("rv:") && -1 == t.appName.indexOf("Netscape") ? !1 : 11, s = -1 == n.indexOf("Edge/") || o || a ? !1 : 12, o = o || a || s, l = !i && !a && /Gecko/.test(n), c = -1 != n.indexOf("Mac"),
                u = /(iPad|iPhone)/.test(n), f = "FormData" in window && "FileReader" in window && "URL" in window && !!URL.createObjectURL, h = e("only screen and (max-device-width: 480px)") && (d || u), p = e("only screen and (min-width: 800px)") && (d || u), s && (i = !1);
            var m = !u || f || n.match(/AppleWebKit\/(\d*)/)[1] >= 534;
            return {
                opera: r,
                webkit: i,
                ie: o,
                gecko: l,
                mac: c,
                iOS: u,
                android: d,
                contentEditable: m,
                transparentSrc: "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",
                caretAfter: 8 != o,
                range: window.getSelection && "Range" in window,
                documentMode: o && !s ? document.documentMode || 7 : 10,
                fileApi: f,
                ceFalse: o === !1 || o > 8,
                desktop: !h && !p
            }
        }), r(p, [], function() {
            function e(e) {
                var t = e,
                    n, r;
                if (!u(e))
                    for (t = [], n = 0, r = e.length; r > n; n++) t[n] = e[n];
                return t
            }
    
            function n(e, n, r) {
                var i, o;
                if (!e) return 0;
                if (r = r || e, e.length !== t) {
                    for (i = 0, o = e.length; o > i; i++)
                        if (n.call(r, e[i], i, e) === !1) return 0
                } else
                    for (i in e)
                        if (e.hasOwnProperty(i) && n.call(r, e[i], i, e) === !1) return 0;
                return 1
            }
    
            function r(e, t) {
                var r = [];
                return n(e, function(n, i) {
                    r.push(t(n, i, e))
                }), r
            }
    
            function i(e, t) {
                var r = [];
                return n(e, function(n, i) {
                    (!t || t(n, i, e)) && r.push(n)
                }), r
            }
    
            function o(e, t) {
                var n, r;
                if (e)
                    for (n = 0, r = e.length; r > n; n++)
                        if (e[n] === t) return n;
                return -1
            }
    
            function a(e, t, n, r) {
                var i = 0;
                for (arguments.length < 3 && (n = e[0]); i < e.length; i++) n = t.call(r, n, e[i], i);
                return n
            }
    
            function s(e, t, n) {
                var r, i;
                for (r = 0, i = e.length; i > r; r++)
                    if (t.call(n, e[r], r, e)) return r;
                return -1
            }
    
            function l(e, n, r) {
                var i = s(e, n, r);
                return -1 !== i ? e[i] : t
            }
    
            function c(e) {
                return e[e.length - 1]
            }
            var u = Array.isArray || function(e) {
                return "[object Array]" === Object.prototype.toString.call(e)
            };
            return {
                isArray: u,
                toArray: e,
                each: n,
                map: r,
                filter: i,
                indexOf: o,
                reduce: a,
                findIndex: s,
                find: l,
                last: c
            }
        }), r(m, [h, p], function(e, n) {
            function r(e) {
                return null === e || e === t ? "" : ("" + e).replace(h, "")
            }
    
            function i(e, r) {
                return r ? "array" == r && n.isArray(e) ? !0 : typeof e == r : e !== t
            }
    
            function o(e, t, n) {
                var r;
                for (e = e || [], t = t || ",", "string" == typeof e && (e = e.split(t)), n = n || {}, r = e.length; r--;) n[e[r]] = {};
                return n
            }
    
            function a(e, t, n) {
                var r = this,
                    i, o, a, s, l, c = 0;
                if (e = /^((static) )?([\w.]+)(:([\w.]+))?/.exec(e), a = e[3].match(/(^|\.)(\w+)$/i)[2], o = r.createNS(e[3].replace(/\.\w+$/, ""), n), !o[a]) {
                    if ("static" == e[2]) return o[a] = t, void(this.onCreate && this.onCreate(e[2], e[3], o[a]));
                    t[a] || (t[a] = function() {}, c = 1), o[a] = t[a], r.extend(o[a].prototype, t), e[5] && (i = r.resolve(e[5]).prototype, s = e[5].match(/\.(\w+)$/i)[1], l = o[a], c ? o[a] = function() {
                        return i[s].apply(this, arguments)
                    } : o[a] = function() {
                        return this.parent = i[s], l.apply(this, arguments)
                    }, o[a].prototype[a] = o[a], r.each(i, function(e, t) {
                        o[a].prototype[t] = i[t]
                    }), r.each(t, function(e, t) {
                        i[t] ? o[a].prototype[t] = function() {
                            return this.parent = i[t], e.apply(this, arguments)
                        } : t != a && (o[a].prototype[t] = e)
                    })), r.each(t["static"], function(e, t) {
                        o[a][t] = e
                    })
                }
            }
    
            function s(e, n) {
                var r, i, o, a = arguments,
                    s;
                for (r = 1, i = a.length; i > r; r++) {
                    n = a[r];
                    for (o in n) n.hasOwnProperty(o) && (s = n[o], s !== t && (e[o] = s))
                }
                return e
            }
    
            function l(e, t, r, i) {
                i = i || this, e && (r && (e = e[r]), n.each(e, function(e, n) {
                    return t.call(i, e, n, r) === !1 ? !1 : void l(e, t, r, i)
                }))
            }
    
            function c(e, t) {
                var n, r;
                for (t = t || window, e = e.split("."), n = 0; n < e.length; n++) r = e[n], t[r] || (t[r] = {}), t = t[r];
                return t
            }
    
            function u(e, t) {
                var n, r;
                for (t = t || window, e = e.split("."), n = 0, r = e.length; r > n && (t = t[e[n]], t); n++);
                return t
            }
    
            function d(e, t) {
                return !e || i(e, "array") ? e : n.map(e.split(t || ","), r)
            }
    
            function f(t) {
                var n = e.cacheSuffix;
                return n && (t += (-1 === t.indexOf("?") ? "?" : "&") + n), t
            }
            var h = /^\s*|\s*$/g;
            return {
                trim: r,
                isArray: n.isArray,
                is: i,
                toArray: n.toArray,
                makeMap: o,
                each: n.each,
                map: n.map,
                grep: n.filter,
                inArray: n.indexOf,
                extend: s,
                create: a,
                walk: l,
                createNS: c,
                resolve: u,
                explode: d,
                _addCacheSuffix: f
            }
        }), r(g, [d, f, m, h], function(e, n, r, i) {
            function o(e) {
                return "undefined" != typeof e
            }
    
            function a(e) {
                return "string" == typeof e
            }
    
            function s(e) {
                return e && e == e.window
            }
    
            function l(e, t) {
                var n, r, i;
                for (t = t || w, i = t.createElement("div"), n = t.createDocumentFragment(), i.innerHTML = e; r = i.firstChild;) n.appendChild(r);
                return n
            }
    
            function c(e, t, n, r) {
                var i;
                if (a(t)) t = l(t, v(e[0]));
                else if (t.length && !t.nodeType) {
                    if (t = f.makeArray(t), r)
                        for (i = t.length - 1; i >= 0; i--) c(e, t[i], n, r);
                    else
                        for (i = 0; i < t.length; i++) c(e, t[i], n, r);
                    return e
                }
                if (t.nodeType)
                    for (i = e.length; i--;) n.call(e[i], t);
                return e
            }
    
            function u(e, t) {
                return e && t && -1 !== (" " + e.className + " ").indexOf(" " + t + " ")
            }
    
            function d(e, t, n) {
                var r, i;
                return t = f(t)[0], e.each(function() {
                    var e = this;
                    n && r == e.parentNode ? i.appendChild(e) : (r = e.parentNode, i = t.cloneNode(!1), e.parentNode.insertBefore(i, e), i.appendChild(e))
                }), e
            }
    
            function f(e, t) {
                return new f.fn.init(e, t)
            }
    
            function h(e, t) {
                var n;
                if (t.indexOf) return t.indexOf(e);
                for (n = t.length; n--;)
                    if (t[n] === e) return n;
                return -1
            }
    
            function p(e) {
                return null === e || e === k ? "" : ("" + e).replace(P, "")
            }
    
            function m(e, t) {
                var n, r, i, o, a;
                if (e)
                    if (n = e.length, n === o) {
                        for (r in e)
                            if (e.hasOwnProperty(r) && (a = e[r], t.call(a, r, a) === !1)) break
                    } else
                        for (i = 0; n > i && (a = e[i], t.call(a, i, a) !== !1); i++);
                return e
            }
    
            function g(e, t) {
                var n = [];
                return m(e, function(e, r) {
                    t(r, e) && n.push(r)
                }), n
            }
    
            function v(e) {
                return e ? 9 == e.nodeType ? e : e.ownerDocument : w
            }
    
            function y(e, n, r) {
                var i = [],
                    o = e[n];
                for ("string" != typeof r && r instanceof f && (r = r[0]); o && 9 !== o.nodeType;) {
                    if (r !== t) {
                        if (o === r) break;
                        if ("string" == typeof r && f(o).is(r)) break
                    }
                    1 === o.nodeType && i.push(o), o = o[n]
                }
                return i
            }
    
            function b(e, n, r, i) {
                var o = [];
                for (i instanceof f && (i = i[0]); e; e = e[n])
                    if (!r || e.nodeType === r) {
                        if (i !== t) {
                            if (e === i) break;
                            if ("string" == typeof i && f(e).is(i)) break
                        }
                        o.push(e)
                    }
                return o
            }
    
            function C(e, t, n) {
                for (e = e[t]; e; e = e[t])
                    if (e.nodeType == n) return e;
                return null
            }
    
            function x(e, t, n) {
                m(n, function(n, r) {
                    e[n] = e[n] || {}, e[n][t] = r
                })
            }
            var w = document,
                E = Array.prototype.push,
                N = Array.prototype.slice,
                _ = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
                S = e.Event,
                k, T = r.makeMap("children,contents,next,prev"),
                R = r.makeMap("fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom", " "),
                A = r.makeMap("checked compact declare defer disabled ismap multiple nohref noshade nowrap readonly selected", " "),
                B = {
                    "for": "htmlFor",
                    "class": "className",
                    readonly: "readOnly"
                },
                D = {
                    "float": "cssFloat"
                },
                M = {},
                L = {},
                P = /^\s*|\s*$/g;
            return f.fn = f.prototype = {
                constructor: f,
                selector: "",
                context: null,
                length: 0,
                init: function(e, t) {
                    var n = this,
                        r, i;
                    if (!e) return n;
                    if (e.nodeType) return n.context = n[0] = e, n.length = 1, n;
                    if (t && t.nodeType) n.context = t;
                    else {
                        if (t) return f(e).attr(t);
                        n.context = t = document
                    }
                    if (a(e)) {
                        if (n.selector = e, r = "<" === e.charAt(0) && ">" === e.charAt(e.length - 1) && e.length >= 3 ? [null, e, null] : _.exec(e), !r) return f(t).find(e);
                        if (r[1])
                            for (i = l(e, v(t)).firstChild; i;) E.call(n, i), i = i.nextSibling;
                        else {
                            if (i = v(t).getElementById(r[2]), !i) return n;
                            if (i.id !== r[2]) return n.find(e);
                            n.length = 1, n[0] = i
                        }
                    } else this.add(e, !1);
                    return n
                },
                toArray: function() {
                    return r.toArray(this)
                },
                add: function(e, t) {
                    var n = this,
                        r, i;
                    if (a(e)) return n.add(f(e));
                    if (t !== !1)
                        for (r = f.unique(n.toArray().concat(f.makeArray(e))), n.length = r.length, i = 0; i < r.length; i++) n[i] = r[i];
                    else E.apply(n, f.makeArray(e));
                    return n
                },
                attr: function(e, t) {
                    var n = this,
                        r;
                    if ("object" == typeof e) m(e, function(e, t) {
                        n.attr(e, t)
                    });
                    else {
                        if (!o(t)) {
                            if (n[0] && 1 === n[0].nodeType) {
                                if (r = M[e], r && r.get) return r.get(n[0], e);
                                if (A[e]) return n.prop(e) ? e : k;
                                t = n[0].getAttribute(e, 2), null === t && (t = k)
                            }
                            return t
                        }
                        this.each(function() {
                            var n;
                            if (1 === this.nodeType) {
                                if (n = M[e], n && n.set) return void n.set(this, t);
                                null === t ? this.removeAttribute(e, 2) : this.setAttribute(e, t, 2)
                            }
                        })
                    }
                    return n
                },
                removeAttr: function(e) {
                    return this.attr(e, null)
                },
                prop: function(e, t) {
                    var n = this;
                    if (e = B[e] || e, "object" == typeof e) m(e, function(e, t) {
                        n.prop(e, t)
                    });
                    else {
                        if (!o(t)) return n[0] && n[0].nodeType && e in n[0] ? n[0][e] : t;
                        this.each(function() {
                            1 == this.nodeType && (this[e] = t)
                        })
                    }
                    return n
                },
                css: function(e, t) {
                    function n(e) {
                        return e.replace(/-(\D)/g, function(e, t) {
                            return t.toUpperCase()
                        })
                    }
    
                    function r(e) {
                        return e.replace(/[A-Z]/g, function(e) {
                            return "-" + e
                        })
                    }
                    var i = this,
                        a, s;
                    if ("object" == typeof e) m(e, function(e, t) {
                        i.css(e, t)
                    });
                    else if (o(t)) e = n(e), "number" != typeof t || R[e] || (t += "px"), i.each(function() {
                        var n = this.style;
                        if (s = L[e], s && s.set) return void s.set(this, t);
                        try {
                            this.style[D[e] || e] = t
                        } catch (i) {}(null === t || "" === t) && (n.removeProperty ? n.removeProperty(r(e)) : n.removeAttribute(e))
                    });
                    else {
                        if (a = i[0], s = L[e], s && s.get) return s.get(a);
                        if (a.ownerDocument.defaultView) try {
                            return a.ownerDocument.defaultView.getComputedStyle(a, null).getPropertyValue(r(e))
                        } catch (l) {
                            return k
                        } else if (a.currentStyle) return a.currentStyle[n(e)]
                    }
                    return i
                },
                remove: function() {
                    for (var e = this, t, n = this.length; n--;) t = e[n], S.clean(t), t.parentNode && t.parentNode.removeChild(t);
                    return this
                },
                empty: function() {
                    for (var e = this, t, n = this.length; n--;)
                        for (t = e[n]; t.firstChild;) t.removeChild(t.firstChild);
                    return this
                },
                html: function(e) {
                    var t = this,
                        n;
                    if (o(e)) {
                        n = t.length;
                        try {
                            for (; n--;) t[n].innerHTML = e
                        } catch (r) {
                            f(t[n]).empty().append(e)
                        }
                        return t
                    }
                    return t[0] ? t[0].innerHTML : ""
                },
                text: function(e) {
                    var t = this,
                        n;
                    if (o(e)) {
                        for (n = t.length; n--;) "innerText" in t[n] ? t[n].innerText = e : t[0].textContent = e;
                        return t
                    }
                    return t[0] ? t[0].innerText || t[0].textContent : ""
                },
                append: function() {
                    return c(this, arguments, function(e) {
                        1 === this.nodeType && this.appendChild(e)
                    })
                },
                prepend: function() {
                    return c(this, arguments, function(e) {
                        1 === this.nodeType && this.insertBefore(e, this.firstChild)
                    }, !0)
                },
                before: function() {
                    var e = this;
                    return e[0] && e[0].parentNode ? c(e, arguments, function(e) {
                        this.parentNode.insertBefore(e, this)
                    }) : e
                },
                after: function() {
                    var e = this;
                    return e[0] && e[0].parentNode ? c(e, arguments, function(e) {
                        this.parentNode.insertBefore(e, this.nextSibling)
                    }, !0) : e
                },
                appendTo: function(e) {
                    return f(e).append(this), this
                },
                prependTo: function(e) {
                    return f(e).prepend(this), this
                },
                replaceWith: function(e) {
                    return this.before(e).remove()
                },
                wrap: function(e) {
                    return d(this, e)
                },
                wrapAll: function(e) {
                    return d(this, e, !0)
                },
                wrapInner: function(e) {
                    return this.each(function() {
                        f(this).contents().wrapAll(e)
                    }), this
                },
                unwrap: function() {
                    return this.parent().each(function() {
                        f(this).replaceWith(this.childNodes)
                    })
                },
                clone: function() {
                    var e = [];
                    return this.each(function() {
                        e.push(this.cloneNode(!0))
                    }), f(e)
                },
                addClass: function(e) {
                    return this.toggleClass(e, !0)
                },
                removeClass: function(e) {
                    return this.toggleClass(e, !1)
                },
                toggleClass: function(e, t) {
                    var n = this;
                    return "string" != typeof e ? n : (-1 !== e.indexOf(" ") ? m(e.split(" "), function() {
                        n.toggleClass(this, t)
                    }) : n.each(function(n, r) {
                        var i, o;
                        o = u(r, e), o !== t && (i = r.className, o ? r.className = p((" " + i + " ").replace(" " + e + " ", " ")) : r.className += i ? " " + e : e)
                    }), n)
                },
                hasClass: function(e) {
                    return u(this[0], e)
                },
                each: function(e) {
                    return m(this, e)
                },
                on: function(e, t) {
                    return this.each(function() {
                        S.bind(this, e, t)
                    })
                },
                off: function(e, t) {
                    return this.each(function() {
                        S.unbind(this, e, t)
                    })
                },
                trigger: function(e) {
                    return this.each(function() {
                        "object" == typeof e ? S.fire(this, e.type, e) : S.fire(this, e)
                    })
                },
                show: function() {
                    return this.css("display", "")
                },
                hide: function() {
                    return this.css("display", "none")
                },
                slice: function() {
                    return new f(N.apply(this, arguments))
                },
                eq: function(e) {
                    return -1 === e ? this.slice(e) : this.slice(e, +e + 1)
                },
                first: function() {
                    return this.eq(0)
                },
                last: function() {
                    return this.eq(-1)
                },
                find: function(e) {
                    var t, n, r = [];
                    for (t = 0, n = this.length; n > t; t++) f.find(e, this[t], r);
                    return f(r)
                },
                filter: function(e) {
                    return f("function" == typeof e ? g(this.toArray(), function(t, n) {
                        return e(n, t)
                    }) : f.filter(e, this.toArray()))
                },
                closest: function(e) {
                    var t = [];
                    return e instanceof f && (e = e[0]), this.each(function(n, r) {
                        for (; r;) {
                            if ("string" == typeof e && f(r).is(e)) {
                                t.push(r);
                                break
                            }
                            if (r == e) {
                                t.push(r);
                                break
                            }
                            r = r.parentNode
                        }
                    }), f(t)
                },
                offset: function(e) {
                    var t, n, r, i = 0,
                        o = 0,
                        a;
                    return e ? this.css(e) : (t = this[0], t && (n = t.ownerDocument, r = n.documentElement, t.getBoundingClientRect && (a = t.getBoundingClientRect(), i = a.left + (r.scrollLeft || n.body.scrollLeft) - r.clientLeft, o = a.top + (r.scrollTop || n.body.scrollTop) - r.clientTop)), {
                        left: i,
                        top: o
                    })
                },
                push: E,
                sort: [].sort,
                splice: [].splice
            }, r.extend(f, {
                extend: r.extend,
                makeArray: function(e) {
                    return s(e) || e.nodeType ? [e] : r.toArray(e)
                },
                inArray: h,
                isArray: r.isArray,
                each: m,
                trim: p,
                grep: g,
                find: n,
                expr: n.selectors,
                unique: n.uniqueSort,
                text: n.getText,
                contains: n.contains,
                filter: function(e, t, n) {
                    var r = t.length;
                    for (n && (e = ":not(" + e + ")"); r--;) 1 != t[r].nodeType && t.splice(r, 1);
                    return t = 1 === t.length ? f.find.matchesSelector(t[0], e) ? [t[0]] : [] : f.find.matches(e, t)
                }
            }), m({
                parent: function(e) {
                    var t = e.parentNode;
                    return t && 11 !== t.nodeType ? t : null
                },
                parents: function(e) {
                    return y(e, "parentNode")
                },
                next: function(e) {
                    return C(e, "nextSibling", 1)
                },
                prev: function(e) {
                    return C(e, "previousSibling", 1)
                },
                children: function(e) {
                    return b(e.firstChild, "nextSibling", 1)
                },
                contents: function(e) {
                    return r.toArray(("iframe" === e.nodeName ? e.contentDocument || e.contentWindow.document : e).childNodes)
                }
            }, function(e, t) {
                f.fn[e] = function(n) {
                    var r = this,
                        i = [];
                    return r.each(function() {
                        var e = t.call(i, this, n, i);
                        e && (f.isArray(e) ? i.push.apply(i, e) : i.push(e))
                    }), this.length > 1 && (T[e] || (i = f.unique(i)), 0 === e.indexOf("parents") && (i = i.reverse())), i = f(i), n ? i.filter(n) : i
                }
            }), m({
                parentsUntil: function(e, t) {
                    return y(e, "parentNode", t)
                },
                nextUntil: function(e, t) {
                    return b(e, "nextSibling", 1, t).slice(1)
                },
                prevUntil: function(e, t) {
                    return b(e, "previousSibling", 1, t).slice(1)
                }
            }, function(e, t) {
                f.fn[e] = function(n, r) {
                    var i = this,
                        o = [];
                    return i.each(function() {
                        var e = t.call(o, this, n, o);
                        e && (f.isArray(e) ? o.push.apply(o, e) : o.push(e))
                    }), this.length > 1 && (o = f.unique(o), (0 === e.indexOf("parents") || "prevUntil" === e) && (o = o.reverse())), o = f(o), r ? o.filter(r) : o
                }
            }), f.fn.is = function(e) {
                return !!e && this.filter(e).length > 0
            }, f.fn.init.prototype = f.fn, f.overrideDefaults = function(e) {
                function t(r, i) {
                    return n = n || e(), 0 === arguments.length && (r = n.element), i || (i = n.context), new t.fn.init(r, i)
                }
                var n;
                return f.extend(t, this), t
            }, i.ie && i.ie < 8 && (x(M, "get", {
                maxlength: function(e) {
                    var t = e.maxLength;
                    return 2147483647 === t ? k : t
                },
                size: function(e) {
                    var t = e.size;
                    return 20 === t ? k : t
                },
                "class": function(e) {
                    return e.className
                },
                style: function(e) {
                    var t = e.style.cssText;
                    return 0 === t.length ? k : t
                }
            }), x(M, "set", {
                "class": function(e, t) {
                    e.className = t
                },
                style: function(e, t) {
                    e.style.cssText = t
                }
            })), i.ie && i.ie < 9 && (D["float"] = "styleFloat", x(L, "set", {
                opacity: function(e, t) {
                    var n = e.style;
                    null === t || "" === t ? n.removeAttribute("filter") : (n.zoom = 1, n.filter = "alpha(opacity=" + 100 * t + ")")
                }
            })), f.attrHooks = M, f.cssHooks = L, f
        }), r(v, [], function() {
            return function(e, t) {
                function n(e, t, n, r) {
                    function i(e) {
                        return e = parseInt(e, 10).toString(16), e.length > 1 ? e : "0" + e
                    }
                    return "#" + i(t) + i(n) + i(r)
                }
                var r = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi,
                    i = /(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi,
                    o = /\s*([^:]+):\s*([^;]+);?/g,
                    a = /\s+$/,
                    s, l, c = {},
                    u, d, f, h = "\ufeff";
                for (e = e || {}, t && (d = t.getValidStyles(), f = t.getInvalidStyles()), u = ("\\\" \\' \\; \\: ; : " + h).split(" "), l = 0; l < u.length; l++) c[u[l]] = h + l, c[h + l] = u[l];
                return {
                    toHex: function(e) {
                        return e.replace(r, n)
                    },
                    parse: function(t) {
                        function s(e, t, n) {
                            var r, i, o, a;
                            if (r = m[e + "-top" + t], r && (i = m[e + "-right" + t], i && (o = m[e + "-bottom" + t], o && (a = m[e + "-left" + t])))) {
                                var s = [r, i, o, a];
                                for (l = s.length - 1; l-- && s[l] === s[l + 1];);
                                l > -1 && n || (m[e + t] = -1 == l ? s[0] : s.join(" "), delete m[e + "-top" + t], delete m[e + "-right" + t], delete m[e + "-bottom" + t], delete m[e + "-left" + t])
                            }
                        }
    
                        function u(e) {
                            var t = m[e],
                                n;
                            if (t) {
                                for (t = t.split(" "), n = t.length; n--;)
                                    if (t[n] !== t[0]) return !1;
                                return m[e] = t[0], !0
                            }
                        }
    
                        function d(e, t, n, r) {
                            u(t) && u(n) && u(r) && (m[e] = m[t] + " " + m[n] + " " + m[r], delete m[t], delete m[n], delete m[r])
                        }
    
                        function f(e) {
                            return b = !0, c[e]
                        }
    
                        function h(e, t) {
                            return b && (e = e.replace(/\uFEFF[0-9]/g, function(e) {
                                return c[e]
                            })), t || (e = e.replace(/\\([\'\";:])/g, "$1")), e
                        }
    
                        function p(t, n, r, i, o, a) {
                            if (o = o || a) return o = h(o), "'" + o.replace(/\'/g, "\\'") + "'";
                            if (n = h(n || r || i), !e.allow_script_urls) {
                                var s = n.replace(/[\s\r\n]+/, "");
                                if (/(java|vb)script:/i.test(s)) return "";
                                if (!e.allow_svg_data_urls && /^data:image\/svg/i.test(s)) return ""
                            }
                            return C && (n = C.call(x, n, "style")), "url('" + n.replace(/\'/g, "\\'") + "')"
                        }
                        var m = {},
                            g, v, y, b, C = e.url_converter,
                            x = e.url_converter_scope || this;
                        if (t) {
                            for (t = t.replace(/[\u0000-\u001F]/g, ""), t = t.replace(/\\[\"\';:\uFEFF]/g, f).replace(/\"[^\"]+\"|\'[^\']+\'/g, function(e) {
                                    return e.replace(/[;:]/g, f)
                                }); g = o.exec(t);) {
                                if (v = g[1].replace(a, "").toLowerCase(), y = g[2].replace(a, ""), y = y.replace(/\\[0-9a-f]+/g, function(e) {
                                        return String.fromCharCode(parseInt(e.substr(1), 16))
                                    }), v && y.length > 0) {
                                    if (!e.allow_script_urls && ("behavior" == v || /expression\s*\(|\/\*|\*\//.test(y))) continue;
                                    "font-weight" === v && "700" === y ? y = "bold" : ("color" === v || "background-color" === v) && (y = y.toLowerCase()), y = y.replace(r, n), y = y.replace(i, p), m[v] = b ? h(y, !0) : y
                                }
                                o.lastIndex = g.index + g[0].length
                            }
                            s("border", "", !0), s("border", "-width"), s("border", "-color"), s("border", "-style"), s("padding", ""), s("margin", ""), d("border", "border-width", "border-style", "border-color"), "medium none" === m.border && delete m.border, "none" === m["border-image"] && delete m["border-image"]
                        }
                        return m
                    },
                    serialize: function(e, t) {
                        function n(t) {
                            var n, r, o, a;
                            if (n = d[t])
                                for (r = 0, o = n.length; o > r; r++) t = n[r], a = e[t], a !== s && a.length > 0 && (i += (i.length > 0 ? " " : "") + t + ": " + a + ";")
                        }
    
                        function r(e, t) {
                            var n;
                            return n = f["*"], n && n[e] ? !1 : (n = f[t], n && n[e] ? !1 : !0)
                        }
                        var i = "",
                            o, a;
                        if (t && d) n("*"), n(t);
                        else
                            for (o in e) a = e[o], a !== s && a.length > 0 && (!f || r(o, t)) && (i += (i.length > 0 ? " " : "") + o + ": " + a + ";");
                        return i
                    }
                }
            }
        }), r(y, [], function() {
            return function(e, t) {
                function n(e, n, r, i) {
                    var o, a;
                    if (e) {
                        if (!i && e[n]) return e[n];
                        if (e != t) {
                            if (o = e[r]) return o;
                            for (a = e.parentNode; a && a != t; a = a.parentNode)
                                if (o = a[r]) return o
                        }
                    }
                }
                var r = e;
                this.current = function() {
                    return r
                }, this.next = function(e) {
                    return r = n(r, "firstChild", "nextSibling", e)
                }, this.prev = function(e) {
                    return r = n(r, "lastChild", "previousSibling", e)
                }
            }
        }), r(b, [m], function(e) {
            function t(n) {
                function r() {
                    return P.createDocumentFragment()
                }
    
                function i(e, t) {
                    E(F, e, t)
                }
    
                function o(e, t) {
                    E(z, e, t)
                }
    
                function a(e) {
                    i(e.parentNode, j(e))
                }
    
                function s(e) {
                    i(e.parentNode, j(e) + 1)
                }
    
                function l(e) {
                    o(e.parentNode, j(e))
                }
    
                function c(e) {
                    o(e.parentNode, j(e) + 1)
                }
    
                function u(e) {
                    e ? (L[U] = L[V], L[$] = L[W]) : (L[V] = L[U], L[W] = L[$]), L.collapsed = F
                }
    
                function d(e) {
                    a(e), c(e)
                }
    
                function f(e) {
                    i(e, 0), o(e, 1 === e.nodeType ? e.childNodes.length : e.nodeValue.length)
                }
    
                function h(e, t) {
                    var n = L[V],
                        r = L[W],
                        i = L[U],
                        o = L[$],
                        a = t.startContainer,
                        s = t.startOffset,
                        l = t.endContainer,
                        c = t.endOffset;
                    return 0 === e ? w(n, r, a, s) : 1 === e ? w(i, o, a, s) : 2 === e ? w(i, o, l, c) : 3 === e ? w(n, r, l, c) : void 0
                }
    
                function p() {
                    N(I)
                }
    
                function m() {
                    return N(H)
                }
    
                function g() {
                    return N(O)
                }
    
                function v(e) {
                    var t = this[V],
                        r = this[W],
                        i, o;
                    3 !== t.nodeType && 4 !== t.nodeType || !t.nodeValue ? (t.childNodes.length > 0 && (o = t.childNodes[r]), o ? t.insertBefore(e, o) : 3 == t.nodeType ? n.insertAfter(e, t) : t.appendChild(e)) : r ? r >= t.nodeValue.length ? n.insertAfter(e, t) : (i = t.splitText(r), t.parentNode.insertBefore(e, i)) : t.parentNode.insertBefore(e, t)
                }
    
                function y(e) {
                    var t = L.extractContents();
                    L.insertNode(e), e.appendChild(t), L.selectNode(e)
                }
    
                function b() {
                    return q(new t(n), {
                        startContainer: L[V],
                        startOffset: L[W],
                        endContainer: L[U],
                        endOffset: L[$],
                        collapsed: L.collapsed,
                        commonAncestorContainer: L.commonAncestorContainer
                    })
                }
    
                function C(e, t) {
                    var n;
                    if (3 == e.nodeType) return e;
                    if (0 > t) return e;
                    for (n = e.firstChild; n && t > 0;) --t, n = n.nextSibling;
                    return n ? n : e
                }
    
                function x() {
                    return L[V] == L[U] && L[W] == L[$]
                }
    
                function w(e, t, r, i) {
                    var o, a, s, l, c, u;
                    if (e == r) return t == i ? 0 : i > t ? -1 : 1;
                    for (o = r; o && o.parentNode != e;) o = o.parentNode;
                    if (o) {
                        for (a = 0, s = e.firstChild; s != o && t > a;) a++, s = s.nextSibling;
                        return a >= t ? -1 : 1
                    }
                    for (o = e; o && o.parentNode != r;) o = o.parentNode;
                    if (o) {
                        for (a = 0, s = r.firstChild; s != o && i > a;) a++, s = s.nextSibling;
                        return i > a ? -1 : 1
                    }
                    for (l = n.findCommonAncestor(e, r), c = e; c && c.parentNode != l;) c = c.parentNode;
                    for (c || (c = l), u = r; u && u.parentNode != l;) u = u.parentNode;
                    if (u || (u = l), c == u) return 0;
                    for (s = l.firstChild; s;) {
                        if (s == c) return -1;
                        if (s == u) return 1;
                        s = s.nextSibling
                    }
                }
    
                function E(e, t, r) {
                    var i, o;
                    for (e ? (L[V] = t, L[W] = r) : (L[U] = t, L[$] = r), i = L[U]; i.parentNode;) i = i.parentNode;
                    for (o = L[V]; o.parentNode;) o = o.parentNode;
                    o == i ? w(L[V], L[W], L[U], L[$]) > 0 && L.collapse(e) : L.collapse(e), L.collapsed = x(), L.commonAncestorContainer = n.findCommonAncestor(L[V], L[U])
                }
    
                function N(e) {
                    var t, n = 0,
                        r = 0,
                        i, o, a, s, l, c;
                    if (L[V] == L[U]) return _(e);
                    for (t = L[U], i = t.parentNode; i; t = i, i = i.parentNode) {
                        if (i == L[V]) return S(t, e);
                        ++n
                    }
                    for (t = L[V], i = t.parentNode; i; t = i, i = i.parentNode) {
                        if (i == L[U]) return k(t, e);
                        ++r
                    }
                    for (o = r - n, a = L[V]; o > 0;) a = a.parentNode, o--;
                    for (s = L[U]; 0 > o;) s = s.parentNode, o++;
                    for (l = a.parentNode, c = s.parentNode; l != c; l = l.parentNode, c = c.parentNode) a = l, s = c;
                    return T(a, s, e)
                }
    
                function _(e) {
                    var t, n, i, o, a, s, l, c, u;
                    if (e != I && (t = r()), L[W] == L[$]) return t;
                    if (3 == L[V].nodeType) {
                        if (n = L[V].nodeValue, i = n.substring(L[W], L[$]), e != O && (o = L[V], c = L[W], u = L[$] - L[W], 0 === c && u >= o.nodeValue.length - 1 ? o.parentNode.removeChild(o) : o.deleteData(c, u), L.collapse(F)), e == I) return;
                        return i.length > 0 && t.appendChild(P.createTextNode(i)), t
                    }
                    for (o = C(L[V], L[W]), a = L[$] - L[W]; o && a > 0;) s = o.nextSibling, l = D(o, e), t && t.appendChild(l), --a, o = s;
                    return e != O && L.collapse(F), t
                }
    
                function S(e, t) {
                    var n, i, o, a, s, l;
                    if (t != I && (n = r()), i = R(e, t), n && n.appendChild(i), o = j(e), a = o - L[W], 0 >= a) return t != O && (L.setEndBefore(e), L.collapse(z)), n;
                    for (i = e.previousSibling; a > 0;) s = i.previousSibling, l = D(i, t), n && n.insertBefore(l, n.firstChild), --a, i = s;
                    return t != O && (L.setEndBefore(e), L.collapse(z)), n
                }
    
                function k(e, t) {
                    var n, i, o, a, s, l;
                    for (t != I && (n = r()), o = A(e, t), n && n.appendChild(o), i = j(e), ++i, a = L[$] - i, o = e.nextSibling; o && a > 0;) s = o.nextSibling, l = D(o, t), n && n.appendChild(l), --a, o = s;
                    return t != O && (L.setStartAfter(e), L.collapse(F)), n
                }
    
                function T(e, t, n) {
                    var i, o, a, s, l, c, u;
                    for (n != I && (o = r()), i = A(e, n), o && o.appendChild(i), a = j(e), s = j(t), ++a, l = s - a, c = e.nextSibling; l > 0;) u = c.nextSibling, i = D(c, n), o && o.appendChild(i), c = u, --l;
                    return i = R(t, n), o && o.appendChild(i), n != O && (L.setStartAfter(e), L.collapse(F)), o
                }
    
                function R(e, t) {
                    var n = C(L[U], L[$] - 1),
                        r, i, o, a, s, l = n != L[U];
                    if (n == e) return B(n, l, z, t);
                    for (r = n.parentNode, i = B(r, z, z, t); r;) {
                        for (; n;) o = n.previousSibling, a = B(n, l, z, t), t != I && i.insertBefore(a, i.firstChild), l = F, n = o;
                        if (r == e) return i;
                        n = r.previousSibling, r = r.parentNode, s = B(r, z, z, t), t != I && s.appendChild(i), i = s
                    }
                }
    
                function A(e, t) {
                    var n = C(L[V], L[W]),
                        r = n != L[V],
                        i, o, a, s, l;
                    if (n == e) return B(n, r, F, t);
                    for (i = n.parentNode, o = B(i, z, F, t); i;) {
                        for (; n;) a = n.nextSibling, s = B(n, r, F, t), t != I && o.appendChild(s), r = F, n = a;
                        if (i == e) return o;
                        n = i.nextSibling, i = i.parentNode, l = B(i, z, F, t), t != I && l.appendChild(o), o = l
                    }
                }
    
                function B(e, t, r, i) {
                    var o, a, s, l, c;
                    if (t) return D(e, i);
                    if (3 == e.nodeType) {
                        if (o = e.nodeValue, r ? (l = L[W], a = o.substring(l), s = o.substring(0, l)) : (l = L[$], a = o.substring(0, l), s = o.substring(l)), i != O && (e.nodeValue = s), i == I) return;
                        return c = n.clone(e, z), c.nodeValue = a, c
                    }
                    if (i != I) return n.clone(e, z)
                }
    
                function D(e, t) {
                    return t != I ? t == O ? n.clone(e, F) : e : void e.parentNode.removeChild(e)
                }
    
                function M() {
                    return n.create("body", null, g()).outerText
                }
                var L = this,
                    P = n.doc,
                    H = 0,
                    O = 1,
                    I = 2,
                    F = !0,
                    z = !1,
                    W = "startOffset",
                    V = "startContainer",
                    U = "endContainer",
                    $ = "endOffset",
                    q = e.extend,
                    j = n.nodeIndex;
                return q(L, {
                    startContainer: P,
                    startOffset: 0,
                    endContainer: P,
                    endOffset: 0,
                    collapsed: F,
                    commonAncestorContainer: P,
                    START_TO_START: 0,
                    START_TO_END: 1,
                    END_TO_END: 2,
                    END_TO_START: 3,
                    setStart: i,
                    setEnd: o,
                    setStartBefore: a,
                    setStartAfter: s,
                    setEndBefore: l,
                    setEndAfter: c,
                    collapse: u,
                    selectNode: d,
                    selectNodeContents: f,
                    compareBoundaryPoints: h,
                    deleteContents: p,
                    extractContents: m,
                    cloneContents: g,
                    insertNode: v,
                    surroundContents: y,
                    cloneRange: b,
                    toStringIE: M
                }), L
            }
            return t.prototype.toString = function() {
                return this.toStringIE()
            }, t
        }), r(C, [m], function(e) {
            function t(e) {
                var t;
                return t = document.createElement("div"), t.innerHTML = e, t.textContent || t.innerText || e
            }
    
            function n(e, t) {
                var n, r, i, a = {};
                if (e) {
                    for (e = e.split(","), t = t || 10, n = 0; n < e.length; n += 2) r = String.fromCharCode(parseInt(e[n], t)), o[r] || (i = "&" + e[n + 1] + ";", a[r] = i, a[i] = r);
                    return a
                }
            }
            var r = e.makeMap,
                i, o, a, s = /[&<>\"\u0060\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
                l = /[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
                c = /[<>&\"\']/g,
                u = /&#([a-z0-9]+);?|&([a-z0-9]+);/gi,
                d = {
                    128: "\u20ac",
                    130: "\u201a",
                    131: "\u0192",
                    132: "\u201e",
                    133: "\u2026",
                    134: "\u2020",
                    135: "\u2021",
                    136: "\u02c6",
                    137: "\u2030",
                    138: "\u0160",
                    139: "\u2039",
                    140: "\u0152",
                    142: "\u017d",
                    145: "\u2018",
                    146: "\u2019",
                    147: "\u201c",
                    148: "\u201d",
                    149: "\u2022",
                    150: "\u2013",
                    151: "\u2014",
                    152: "\u02dc",
                    153: "\u2122",
                    154: "\u0161",
                    155: "\u203a",
                    156: "\u0153",
                    158: "\u017e",
                    159: "\u0178"
                };
            o = {
                '"': "&quot;",
                "'": "&#39;",
                "<": "&lt;",
                ">": "&gt;",
                "&": "&amp;",
                "`": "&#96;"
            }, a = {
                "&lt;": "<",
                "&gt;": ">",
                "&amp;": "&",
                "&quot;": '"',
                "&apos;": "'"
            }, i = n("50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,t9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro", 32);
            var f = {
                encodeRaw: function(e, t) {
                    return e.replace(t ? s : l, function(e) {
                        return o[e] || e
                    })
                },
                encodeAllRaw: function(e) {
                    return ("" + e).replace(c, function(e) {
                        return o[e] || e
                    })
                },
                encodeNumeric: function(e, t) {
                    return e.replace(t ? s : l, function(e) {
                        return e.length > 1 ? "&#" + (1024 * (e.charCodeAt(0) - 55296) + (e.charCodeAt(1) - 56320) + 65536) + ";" : o[e] || "&#" + e.charCodeAt(0) + ";"
                    })
                },
                encodeNamed: function(e, t, n) {
                    return n = n || i, e.replace(t ? s : l, function(e) {
                        return o[e] || n[e] || e
                    })
                },
                getEncodeFunc: function(e, t) {
                    function a(e, n) {
                        return e.replace(n ? s : l, function(e) {
                            return o[e] || t[e] || "&#" + e.charCodeAt(0) + ";" || e
                        })
                    }
    
                    function c(e, n) {
                        return f.encodeNamed(e, n, t)
                    }
                    return t = n(t) || i, e = r(e.replace(/\+/g, ",")), e.named && e.numeric ? a : e.named ? t ? c : f.encodeNamed : e.numeric ? f.encodeNumeric : f.encodeRaw
                },
                decode: function(e) {
                    return e.replace(u, function(e, n) {
                        return n ? (n = "x" === n.charAt(0).toLowerCase() ? parseInt(n.substr(1), 16) : parseInt(n, 10), n > 65535 ? (n -= 65536, String.fromCharCode(55296 + (n >> 10), 56320 + (1023 & n))) : d[n] || String.fromCharCode(n)) : a[e] || i[e] || t(e)
                    })
                }
            };
            return f
        }), r(x, [m, u], function(e, t) {
            return function(n, r) {
                function i(e) {
                    n.getElementsByTagName("head")[0].appendChild(e)
                }
    
                function o(r, o, c) {
                    function u() {
                        for (var e = b.passed, t = e.length; t--;) e[t]();
                        b.status = 2, b.passed = [], b.failed = []
                    }
    
                    function d() {
                        for (var e = b.failed, t = e.length; t--;) e[t]();
                        b.status = 3, b.passed = [], b.failed = []
                    }
    
                    function f() {
                        var e = navigator.userAgent.match(/WebKit\/(\d*)/);
                        return !!(e && e[1] < 536)
                    }
    
                    function h(e, n) {
                        e() || ((new Date).getTime() - y < l ? t.setTimeout(n) : d())
                    }
    
                    function p() {
                        h(function() {
                            for (var e = n.styleSheets, t, r = e.length, i; r--;)
                                if (t = e[r], i = t.ownerNode ? t.ownerNode : t.owningElement, i && i.id === g.id) return u(), !0
                        }, p)
                    }
    
                    function m() {
                        h(function() {
                            try {
                                var e = v.sheet.cssRules;
                                return u(), !!e
                            } catch (t) {}
                        }, m)
                    }
                    var g, v, y, b;
                    if (r = e._addCacheSuffix(r), s[r] ? b = s[r] : (b = {
                            passed: [],
                            failed: []
                        }, s[r] = b), o && b.passed.push(o), c && b.failed.push(c), 1 != b.status) {
                        if (2 == b.status) return void u();
                        if (3 == b.status) return void d();
                        if (b.status = 1, g = n.createElement("link"), g.rel = "stylesheet", g.type = "text/css", g.id = "u" + a++, g.async = !1, g.defer = !1, y = (new Date).getTime(), "onload" in g && !f()) g.onload = p, g.onerror = d;
                        else {
                            if (navigator.userAgent.indexOf("Firefox") > 0) return v = n.createElement("style"), v.textContent = '@import "' + r + '"', m(), void i(v);
                            p()
                        }
                        i(g), g.href = r
                    }
                }
                var a = 0,
                    s = {},
                    l;
                r = r || {}, l = r.maxLoadTime || 5e3, this.load = o
            }
        }), r(w, [f, g, v, d, y, b, C, h, m, x], function(e, n, r, i, o, a, s, l, c, u) {
            function d(e, t) {
                var n = {},
                    r = t.keep_values,
                    i;
                return i = {
                    set: function(n, r, i) {
                        t.url_converter && (r = t.url_converter.call(t.url_converter_scope || e, r, i, n[0])), n.attr("data-mce-" + i, r).attr(i, r)
                    },
                    get: function(e, t) {
                        return e.attr("data-mce-" + t) || e.attr(t)
                    }
                }, n = {
                    style: {
                        set: function(e, t) {
                            return null !== t && "object" == typeof t ? void e.css(t) : (r && e.attr("data-mce-style", t), void e.attr("style", t))
                        },
                        get: function(t) {
                            var n = t.attr("data-mce-style") || t.attr("style");
                            return n = e.serializeStyle(e.parseStyle(n), t[0].nodeName)
                        }
                    }
                }, r && (n.href = n.src = i), n
            }
    
            function f(e, t) {
                var n = t.attr("style");
                n = e.serializeStyle(e.parseStyle(n), t[0].nodeName), n || (n = null), t.attr("data-mce-style", n)
            }
    
            function h(e, t) {
                var n = 0,
                    r, i;
                if (e)
                    for (r = e.nodeType, e = e.previousSibling; e; e = e.previousSibling) i = e.nodeType, (!t || 3 != i || i != r && e.nodeValue.length) && (n++, r = i);
                return n
            }
    
            function p(e, t) {
                var o = this,
                    a;
                o.doc = e, o.win = window, o.files = {}, o.counter = 0, o.stdMode = !b || e.documentMode >= 8, o.boxModel = !b || "CSS1Compat" == e.compatMode || o.stdMode, o.styleSheetLoader = new u(e), o.boundEvents = [], o.settings = t = t || {}, o.schema = t.schema, o.styles = new r({
                    url_converter: t.url_converter,
                    url_converter_scope: t.url_converter_scope
                }, t.schema), o.fixDoc(e), o.events = t.ownEvents ? new i(t.proxy) : i.Event, o.attrHooks = d(o, t), a = t.schema ? t.schema.getBlockElements() : {}, o.$ = n.overrideDefaults(function() {
                    return {
                        context: e,
                        element: o.getRoot()
                    }
                }), o.isBlock = function(e) {
                    if (!e) return !1;
                    var t = e.nodeType;
                    return t ? !(1 !== t || !a[e.nodeName]) : !!a[e]
                }
            }
            var m = c.each,
                g = c.is,
                v = c.grep,
                y = c.trim,
                b = l.ie,
                C = /^([a-z0-9],?)+$/i,
                x = /^[ \t\r\n]*$/;
            return p.prototype = {
                $$: function(e) {
                    return "string" == typeof e && (e = this.get(e)), this.$(e)
                },
                root: null,
                fixDoc: function(e) {
                    var t = this.settings,
                        n;
                    if (b && t.schema) {
                        "abbr article aside audio canvas details figcaption figure footer header hgroup mark menu meter nav output progress section summary time video".replace(/\w+/g, function(t) {
                            e.createElement(t)
                        });
                        for (n in t.schema.getCustomElements()) e.createElement(n)
                    }
                },
                clone: function(e, t) {
                    var n = this,
                        r, i;
                    return !b || 1 !== e.nodeType || t ? e.cloneNode(t) : (i = n.doc, t ? r.firstChild : (r = i.createElement(e.nodeName), m(n.getAttribs(e), function(t) {
                        n.setAttrib(r, t.nodeName, n.getAttrib(e, t.nodeName))
                    }), r))
                },
                getRoot: function() {
                    var e = this;
                    return e.settings.root_element || e.doc.body
                },
                getViewPort: function(e) {
                    var t, n;
                    return e = e ? e : this.win, t = e.document, n = this.boxModel ? t.documentElement : t.body, {
                        x: e.pageXOffset || n.scrollLeft,
                        y: e.pageYOffset || n.scrollTop,
                        w: e.innerWidth || n.clientWidth,
                        h: e.innerHeight || n.clientHeight
                    }
                },
                getRect: function(e) {
                    var t = this,
                        n, r;
                    return e = t.get(e), n = t.getPos(e), r = t.getSize(e), {
                        x: n.x,
                        y: n.y,
                        w: r.w,
                        h: r.h
                    }
                },
                getSize: function(e) {
                    var t = this,
                        n, r;
                    return e = t.get(e), n = t.getStyle(e, "width"), r = t.getStyle(e, "height"), -1 === n.indexOf("px") && (n = 0), -1 === r.indexOf("px") && (r = 0), {
                        w: parseInt(n, 10) || e.offsetWidth || e.clientWidth,
                        h: parseInt(r, 10) || e.offsetHeight || e.clientHeight
                    }
                },
                getParent: function(e, t, n) {
                    return this.getParents(e, t, n, !1)
                },
                getParents: function(e, n, r, i) {
                    var o = this,
                        a, s = [];
                    for (e = o.get(e), i = i === t, r = r || ("BODY" != o.getRoot().nodeName ? o.getRoot().parentNode : null), g(n, "string") && (a = n, n = "*" === n ? function(e) {
                            return 1 == e.nodeType
                        } : function(e) {
                            return o.is(e, a)
                        }); e && e != r && e.nodeType && 9 !== e.nodeType;) {
                        if (!n || n(e)) {
                            if (!i) return e;
                            s.push(e)
                        }
                        e = e.parentNode
                    }
                    return i ? s : null
                },
                get: function(e) {
                    var t;
                    return e && this.doc && "string" == typeof e && (t = e, e = this.doc.getElementById(e), e && e.id !== t) ? this.doc.getElementsByName(t)[1] : e
                },
                getNext: function(e, t) {
                    return this._findSib(e, t, "nextSibling")
                },
                getPrev: function(e, t) {
                    return this._findSib(e, t, "previousSibling")
                },
                select: function(t, n) {
                    var r = this;
                    return e(t, r.get(n) || r.settings.root_element || r.doc, [])
                },
                is: function(n, r) {
                    var i;
                    if (n.length === t) {
                        if ("*" === r) return 1 == n.nodeType;
                        if (C.test(r)) {
                            for (r = r.toLowerCase().split(/,/), n = n.nodeName.toLowerCase(), i = r.length - 1; i >= 0; i--)
                                if (r[i] == n) return !0;
                            return !1
                        }
                    }
                    if (n.nodeType && 1 != n.nodeType) return !1;
                    var o = n.nodeType ? [n] : n;
                    return e(r, o[0].ownerDocument || o[0], null, o).length > 0;
                },
                add: function(e, t, n, r, i) {
                    var o = this;
                    return this.run(e, function(e) {
                        var a;
                        return a = g(t, "string") ? o.doc.createElement(t) : t, o.setAttribs(a, n), r && (r.nodeType ? a.appendChild(r) : o.setHTML(a, r)), i ? a : e.appendChild(a)
                    })
                },
                create: function(e, t, n) {
                    return this.add(this.doc.createElement(e), e, t, n, 1)
                },
                createHTML: function(e, t, n) {
                    var r = "",
                        i;
                    r += "<" + e;
                    for (i in t) t.hasOwnProperty(i) && null !== t[i] && "undefined" != typeof t[i] && (r += " " + i + '="' + this.encode(t[i]) + '"');
                    return "undefined" != typeof n ? r + ">" + n + "</" + e + ">" : r + " />"
                },
                createFragment: function(e) {
                    var t, n, r = this.doc,
                        i;
                    for (i = r.createElement("div"), t = r.createDocumentFragment(), e && (i.innerHTML = e); n = i.firstChild;) t.appendChild(n);
                    return t
                },
                remove: function(e, t) {
                    return e = this.$$(e), t ? e.each(function() {
                        for (var e; e = this.firstChild;) 3 == e.nodeType && 0 === e.data.length ? this.removeChild(e) : this.parentNode.insertBefore(e, this)
                    }).remove() : e.remove(), e.length > 1 ? e.toArray() : e[0]
                },
                setStyle: function(e, t, n) {
                    e = this.$$(e).css(t, n), this.settings.update_styles && f(this, e)
                },
                getStyle: function(e, n, r) {
                    return e = this.$$(e), r ? e.css(n) : (n = n.replace(/-(\D)/g, function(e, t) {
                        return t.toUpperCase()
                    }), "float" == n && (n = l.ie && l.ie < 12 ? "styleFloat" : "cssFloat"), e[0] && e[0].style ? e[0].style[n] : t)
                },
                setStyles: function(e, t) {
                    e = this.$$(e).css(t), this.settings.update_styles && f(this, e)
                },
                removeAllAttribs: function(e) {
                    return this.run(e, function(e) {
                        var t, n = e.attributes;
                        for (t = n.length - 1; t >= 0; t--) e.removeAttributeNode(n.item(t))
                    })
                },
                setAttrib: function(e, t, n) {
                    var r = this,
                        i, o, a = r.settings;
                    "" === n && (n = null), e = r.$$(e), i = e.attr(t), e.length && (o = r.attrHooks[t], o && o.set ? o.set(e, n, t) : e.attr(t, n), i != n && a.onSetAttrib && a.onSetAttrib({
                        attrElm: e,
                        attrName: t,
                        attrValue: n
                    }))
                },
                setAttribs: function(e, t) {
                    var n = this;
                    n.$$(e).each(function(e, r) {
                        m(t, function(e, t) {
                            n.setAttrib(r, t, e)
                        })
                    })
                },
                getAttrib: function(e, t, n) {
                    var r = this,
                        i, o;
                    return e = r.$$(e), e.length && (i = r.attrHooks[t], o = i && i.get ? i.get(e, t) : e.attr(t)), "undefined" == typeof o && (o = n || ""), o
                },
                getPos: function(e, t) {
                    var r = this,
                        i = 0,
                        o = 0,
                        a, s = r.doc,
                        l = s.body,
                        c;
                    if (e = r.get(e), t = t || l, e) {
                        if (t === l && e.getBoundingClientRect && "static" === n(l).css("position")) return c = e.getBoundingClientRect(), t = r.boxModel ? s.documentElement : l, i = c.left + (s.documentElement.scrollLeft || l.scrollLeft) - t.clientLeft, o = c.top + (s.documentElement.scrollTop || l.scrollTop) - t.clientTop, {
                            x: i,
                            y: o
                        };
                        for (a = e; a && a != t && a.nodeType;) i += a.offsetLeft || 0, o += a.offsetTop || 0, a = a.offsetParent;
                        for (a = e.parentNode; a && a != t && a.nodeType;) i -= a.scrollLeft || 0, o -= a.scrollTop || 0, a = a.parentNode
                    }
                    return {
                        x: i,
                        y: o
                    }
                },
                parseStyle: function(e) {
                    return this.styles.parse(e)
                },
                serializeStyle: function(e, t) {
                    return this.styles.serialize(e, t)
                },
                addStyle: function(e) {
                    var t = this,
                        n = t.doc,
                        r, i;
                    if (t !== p.DOM && n === document) {
                        var o = p.DOM.addedStyles;
                        if (o = o || [], o[e]) return;
                        o[e] = !0, p.DOM.addedStyles = o
                    }
                    i = n.getElementById("mceDefaultStyles"), i || (i = n.createElement("style"), i.id = "mceDefaultStyles", i.type = "text/css", r = n.getElementsByTagName("head")[0], r.firstChild ? r.insertBefore(i, r.firstChild) : r.appendChild(i)), i.styleSheet ? i.styleSheet.cssText += e : i.appendChild(n.createTextNode(e))
                },
                loadCSS: function(e) {
                    var t = this,
                        n = t.doc,
                        r;
                    return t !== p.DOM && n === document ? void p.DOM.loadCSS(e) : (e || (e = ""), r = n.getElementsByTagName("head")[0], void m(e.split(","), function(e) {
                        var i;
                        e = c._addCacheSuffix(e), t.files[e] || (t.files[e] = !0, i = t.create("link", {
                            rel: "stylesheet",
                            href: e
                        }), b && n.documentMode && n.recalc && (i.onload = function() {
                            n.recalc && n.recalc(), i.onload = null
                        }), r.appendChild(i))
                    }))
                },
                addClass: function(e, t) {
                    this.$$(e).addClass(t)
                },
                removeClass: function(e, t) {
                    this.toggleClass(e, t, !1)
                },
                hasClass: function(e, t) {
                    return this.$$(e).hasClass(t)
                },
                toggleClass: function(e, t, r) {
                    this.$$(e).toggleClass(t, r).each(function() {
                        "" === this.className && n(this).attr("class", null)
                    })
                },
                show: function(e) {
                    this.$$(e).show()
                },
                hide: function(e) {
                    this.$$(e).hide()
                },
                isHidden: function(e) {
                    return "none" == this.$$(e).css("display")
                },
                uniqueId: function(e) {
                    return (e ? e : "mce_") + this.counter++
                },
                setHTML: function(e, t) {
                    e = this.$$(e), b ? e.each(function(e, r) {
                        if (r.canHaveHTML !== !1) {
                            for (; r.firstChild;) r.removeChild(r.firstChild);
                            try {
                                r.innerHTML = "<br>" + t, r.removeChild(r.firstChild)
                            } catch (i) {
                                n("<div>").html("<br>" + t).contents().slice(1).appendTo(r)
                            }
                            return t
                        }
                    }) : e.html(t)
                },
                getOuterHTML: function(e) {
                    return e = this.get(e), 1 == e.nodeType && "outerHTML" in e ? e.outerHTML : n("<div>").append(n(e).clone()).html()
                },
                setOuterHTML: function(e, t) {
                    var r = this;
                    r.$$(e).each(function() {
                        try {
                            if ("outerHTML" in this) return void(this.outerHTML = t)
                        } catch (e) {}
                        r.remove(n(this).html(t), !0)
                    })
                },
                decode: s.decode,
                encode: s.encodeAllRaw,
                insertAfter: function(e, t) {
                    return t = this.get(t), this.run(e, function(e) {
                        var n, r;
                        return n = t.parentNode, r = t.nextSibling, r ? n.insertBefore(e, r) : n.appendChild(e), e
                    })
                },
                replace: function(e, t, n) {
                    var r = this;
                    return r.run(t, function(t) {
                        return g(t, "array") && (e = e.cloneNode(!0)), n && m(v(t.childNodes), function(t) {
                            e.appendChild(t)
                        }), t.parentNode.replaceChild(e, t)
                    })
                },
                rename: function(e, t) {
                    var n = this,
                        r;
                    return e.nodeName != t.toUpperCase() && (r = n.create(t), m(n.getAttribs(e), function(t) {
                        n.setAttrib(r, t.nodeName, n.getAttrib(e, t.nodeName))
                    }), n.replace(r, e, 1)), r || e
                },
                findCommonAncestor: function(e, t) {
                    for (var n = e, r; n;) {
                        for (r = t; r && n != r;) r = r.parentNode;
                        if (n == r) break;
                        n = n.parentNode
                    }
                    return !n && e.ownerDocument ? e.ownerDocument.documentElement : n
                },
                toHex: function(e) {
                    return this.styles.toHex(c.trim(e))
                },
                run: function(e, t, n) {
                    var r = this,
                        i;
                    return "string" == typeof e && (e = r.get(e)), e ? (n = n || this, e.nodeType || !e.length && 0 !== e.length ? t.call(n, e) : (i = [], m(e, function(e, o) {
                        e && ("string" == typeof e && (e = r.get(e)), i.push(t.call(n, e, o)))
                    }), i)) : !1
                },
                getAttribs: function(e) {
                    var t;
                    if (e = this.get(e), !e) return [];
                    if (b) {
                        if (t = [], "OBJECT" == e.nodeName) return e.attributes;
                        "OPTION" === e.nodeName && this.getAttrib(e, "selected") && t.push({
                            specified: 1,
                            nodeName: "selected"
                        });
                        var n = /<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi;
                        return e.cloneNode(!1).outerHTML.replace(n, "").replace(/[\w:\-]+/gi, function(e) {
                            t.push({
                                specified: 1,
                                nodeName: e
                            })
                        }), t
                    }
                    return e.attributes
                },
                isEmpty: function(e, t) {
                    var n = this,
                        r, i, a, s, l, c = 0;
                    if (e = e.firstChild) {
                        s = new o(e, e.parentNode), t = t || (n.schema ? n.schema.getNonEmptyElements() : null);
                        do {
                            if (a = e.nodeType, 1 === a) {
                                if (e.getAttribute("data-mce-bogus")) continue;
                                if (l = e.nodeName.toLowerCase(), t && t[l]) {
                                    if ("br" === l) {
                                        c++;
                                        continue
                                    }
                                    return !1
                                }
                                for (i = n.getAttribs(e), r = i.length; r--;)
                                    if (l = i[r].nodeName, "name" === l || "data-mce-bookmark" === l) return !1
                            }
                            if (8 == a) return !1;
                            if (3 === a && !x.test(e.nodeValue)) return !1
                        } while (e = s.next())
                    }
                    return 1 >= c
                },
                createRng: function() {
                    var e = this.doc;
                    return e.createRange ? e.createRange() : new a(this)
                },
                nodeIndex: h,
                split: function(e, t, n) {
                    function r(e) {
                        function t(e) {
                            var t = e.previousSibling && "SPAN" == e.previousSibling.nodeName,
                                n = e.nextSibling && "SPAN" == e.nextSibling.nodeName;
                            return t && n
                        }
                        var n, o = e.childNodes,
                            a = e.nodeType;
                        if (1 != a || "bookmark" != e.getAttribute("data-mce-type")) {
                            for (n = o.length - 1; n >= 0; n--) r(o[n]);
                            if (9 != a) {
                                if (3 == a && e.nodeValue.length > 0) {
                                    var s = y(e.nodeValue).length;
                                    if (!i.isBlock(e.parentNode) || s > 0 || 0 === s && t(e)) return
                                } else if (1 == a && (o = e.childNodes, 1 == o.length && o[0] && 1 == o[0].nodeType && "bookmark" == o[0].getAttribute("data-mce-type") && e.parentNode.insertBefore(o[0], e), o.length || /^(br|hr|input|img)$/i.test(e.nodeName))) return;
                                i.remove(e)
                            }
                            return e
                        }
                    }
                    var i = this,
                        o = i.createRng(),
                        a, s, l;
                    return e && t ? (o.setStart(e.parentNode, i.nodeIndex(e)), o.setEnd(t.parentNode, i.nodeIndex(t)), a = o.extractContents(), o = i.createRng(), o.setStart(t.parentNode, i.nodeIndex(t) + 1), o.setEnd(e.parentNode, i.nodeIndex(e) + 1), s = o.extractContents(), l = e.parentNode, l.insertBefore(r(a), e), n ? l.insertBefore(n, e) : l.insertBefore(t, e), l.insertBefore(r(s), e), i.remove(e), n || t) : void 0
                },
                bind: function(e, t, n, r) {
                    var i = this;
                    if (c.isArray(e)) {
                        for (var o = e.length; o--;) e[o] = i.bind(e[o], t, n, r);
                        return e
                    }
                    return !i.settings.collect || e !== i.doc && e !== i.win || i.boundEvents.push([e, t, n, r]), i.events.bind(e, t, n, r || i)
                },
                unbind: function(e, t, n) {
                    var r = this,
                        i;
                    if (c.isArray(e)) {
                        for (i = e.length; i--;) e[i] = r.unbind(e[i], t, n);
                        return e
                    }
                    if (r.boundEvents && (e === r.doc || e === r.win))
                        for (i = r.boundEvents.length; i--;) {
                            var o = r.boundEvents[i];
                            e != o[0] || t && t != o[1] || n && n != o[2] || this.events.unbind(o[0], o[1], o[2])
                        }
                    return this.events.unbind(e, t, n)
                },
                fire: function(e, t, n) {
                    return this.events.fire(e, t, n)
                },
                getContentEditable: function(e) {
                    var t;
                    return e && 1 == e.nodeType ? (t = e.getAttribute("data-mce-contenteditable"), t && "inherit" !== t ? t : "inherit" !== e.contentEditable ? e.contentEditable : null) : null
                },
                getContentEditableParent: function(e) {
                    for (var t = this.getRoot(), n = null; e && e !== t && (n = this.getContentEditable(e), null === n); e = e.parentNode);
                    return n
                },
                destroy: function() {
                    var t = this;
                    if (t.boundEvents) {
                        for (var n = t.boundEvents.length; n--;) {
                            var r = t.boundEvents[n];
                            this.events.unbind(r[0], r[1], r[2])
                        }
                        t.boundEvents = null
                    }
                    e.setDocument && e.setDocument(), t.win = t.doc = t.root = t.events = t.frag = null
                },
                isChildOf: function(e, t) {
                    for (; e;) {
                        if (t === e) return !0;
                        e = e.parentNode
                    }
                    return !1
                },
                dumpRng: function(e) {
                    return "startContainer: " + e.startContainer.nodeName + ", startOffset: " + e.startOffset + ", endContainer: " + e.endContainer.nodeName + ", endOffset: " + e.endOffset
                },
                _findSib: function(e, t, n) {
                    var r = this,
                        i = t;
                    if (e)
                        for ("string" == typeof i && (i = function(e) {
                                return r.is(e, t)
                            }), e = e[n]; e; e = e[n])
                            if (i(e)) return e;
                    return null
                }
            }, p.DOM = new p(document), p.nodeIndex = h, p
        }), r(E, [w, m], function(e, t) {
            function n() {
                function e(e, n) {
                    function i() {
                        a.remove(l), s && (s.onreadystatechange = s.onload = s = null), n()
                    }
    
                    function o() {
                        "undefined" != typeof console && console.log && console.log("Failed to load: " + e)
                    }
                    var a = r,
                        s, l;
                    l = a.uniqueId(), s = document.createElement("script"), s.id = l, s.type = "text/javascript", s.src = t._addCacheSuffix(e), "onreadystatechange" in s ? s.onreadystatechange = function() {
                        /loaded|complete/.test(s.readyState) && i()
                    } : s.onload = i, s.onerror = o, (document.getElementsByTagName("head")[0] || document.body).appendChild(s)
                }
                var n = 0,
                    a = 1,
                    s = 2,
                    l = {},
                    c = [],
                    u = {},
                    d = [],
                    f = 0,
                    h;
                this.isDone = function(e) {
                    return l[e] == s
                }, this.markDone = function(e) {
                    l[e] = s
                }, this.add = this.load = function(e, t, r) {
                    var i = l[e];
                    i == h && (c.push(e), l[e] = n), t && (u[e] || (u[e] = []), u[e].push({
                        func: t,
                        scope: r || this
                    }))
                }, this.loadQueue = function(e, t) {
                    this.loadScripts(c, e, t)
                }, this.loadScripts = function(t, n, r) {
                    function c(e) {
                        i(u[e], function(e) {
                            e.func.call(e.scope)
                        }), u[e] = h
                    }
                    var p;
                    d.push({
                        func: n,
                        scope: r || this
                    }), (p = function() {
                        var n = o(t);
                        t.length = 0, i(n, function(t) {
                            return l[t] == s ? void c(t) : void(l[t] != a && (l[t] = a, f++, e(t, function() {
                                l[t] = s, f--, c(t), p()
                            })))
                        }), f || (i(d, function(e) {
                            e.func.call(e.scope)
                        }), d.length = 0)
                    })()
                }
            }
            var r = e.DOM,
                i = t.each,
                o = t.grep;
            return n.ScriptLoader = new n, n
        }), r(N, [E, m], function(e, n) {
            function r() {
                var e = this;
                e.items = [], e.urls = {}, e.lookup = {}
            }
            var i = n.each;
            return r.prototype = {
                get: function(e) {
                    return this.lookup[e] ? this.lookup[e].instance : t
                },
                dependencies: function(e) {
                    var t;
                    return this.lookup[e] && (t = this.lookup[e].dependencies), t || []
                },
                requireLangPack: function(t, n) {
                    var i = r.language;
                    if (i && r.languageLoad !== !1) {
                        if (n)
                            if (n = "," + n + ",", -1 != n.indexOf("," + i.substr(0, 2) + ",")) i = i.substr(0, 2);
                            else if (-1 == n.indexOf("," + i + ",")) return;
                        e.ScriptLoader.add(this.urls[t] + "/langs/" + i + ".js")
                    }
                },
                add: function(e, t, n) {
                    return this.items.push(t), this.lookup[e] = {
                        instance: t,
                        dependencies: n
                    }, t
                },
                createUrl: function(e, t) {
                    return "object" == typeof t ? t : {
                        prefix: e.prefix,
                        resource: t,
                        suffix: e.suffix
                    }
                },
                addComponents: function(t, n) {
                    var r = this.urls[t];
                    i(n, function(t) {
                        e.ScriptLoader.add(r + "/" + t)
                    })
                },
                load: function(n, o, a, s) {
                    function l() {
                        var r = c.dependencies(n);
                        i(r, function(e) {
                            var n = c.createUrl(o, e);
                            c.load(n.resource, n, t, t)
                        }), a && (s ? a.call(s) : a.call(e))
                    }
                    var c = this,
                        u = o;
                    c.urls[n] || ("object" == typeof o && (u = o.prefix + o.resource + o.suffix), 0 !== u.indexOf("/") && -1 == u.indexOf("://") && (u = r.baseURL + "/" + u), c.urls[n] = u.substring(0, u.lastIndexOf("/")), c.lookup[n] ? l() : e.ScriptLoader.add(u, l, s))
                }
            }, r.PluginManager = new r, r.ThemeManager = new r, r
        }), r(_, [], function() {
            function e(e) {
                return function(t) {
                    return !!t && t.nodeType == e
                }
            }
    
            function t(e) {
                return e = e.toLowerCase().split(" "),
                    function(t) {
                        var n, r;
                        if (t && t.nodeType)
                            for (r = t.nodeName.toLowerCase(), n = 0; n < e.length; n++)
                                if (r === e[n]) return !0;
                        return !1
                    }
            }
    
            function n(e, t) {
                return t = t.toLowerCase().split(" "),
                    function(n) {
                        var r, i;
                        if (s(n))
                            for (r = 0; r < t.length; r++)
                                if (i = getComputedStyle(n, null).getPropertyValue(e), i === t[r]) return !0;
                        return !1
                    }
            }
    
            function r(e, t) {
                return function(n) {
                    return s(n) && n[e] === t
                }
            }
    
            function i(e, t) {
                return function(n) {
                    return s(n) && n.getAttribute(e) === t
                }
            }
    
            function o(e) {
                return s(e) && e.hasAttribute("data-mce-bogus")
            }
    
            function a(e) {
                return function(t) {
                    if (s(t)) {
                        if (t.contentEditable === e) return !0;
                        if (t.getAttribute("data-mce-contenteditable") === e) return !0
                    }
                    return !1
                }
            }
            var s = e(1);
            return {
                isText: e(3),
                isElement: s,
                isComment: e(8),
                isBr: t("br"),
                isContentEditableTrue: a("true"),
                isContentEditableFalse: a("false"),
                matchNodeNames: t,
                hasPropValue: r,
                hasAttributeValue: i,
                matchStyleValues: n,
                isBogus: o
            }
        }), r(S, [], function() {
            function e(e) {
                return e == n
            }
    
            function t(e) {
                return e.replace(new RegExp(n, "g"), "")
            }
            var n = "\u200b";
            return {
                isZwsp: e,
                ZWSP: n,
                trim: t
            }
        }), r(k, [_, S], function(e, t) {
            function n(e) {
                return d(e) && (e = e.parentNode), u(e) && e.hasAttribute("data-mce-caret")
            }
    
            function r(e) {
                return d(e) && t.isZwsp(e.data)
            }
    
            function i(e) {
                return n(e) || r(e)
            }
    
            function o(e, n) {
                var r, o, a, s;
                if (r = e.ownerDocument, a = r.createTextNode(t.ZWSP), s = e.parentNode, n) {
                    if (o = e.previousSibling, d(o)) {
                        if (i(o)) return o;
                        if (c(o)) return o.splitText(o.data.length - 1)
                    }
                    s.insertBefore(a, e)
                } else {
                    if (o = e.nextSibling, d(o)) {
                        if (i(o)) return o;
                        if (l(o)) return o.splitText(1), o
                    }
                    e.nextSibling ? s.insertBefore(a, e.nextSibling) : s.appendChild(a)
                }
                return a
            }
    
            function a(e, t, n) {
                var r, i, o;
                return r = t.ownerDocument, i = r.createElement(e), i.setAttribute("data-mce-caret", n ? "before" : "after"), i.setAttribute("data-mce-bogus", "all"), i.appendChild(r.createTextNode("\xa0")), o = t.parentNode, n ? o.insertBefore(i, t) : t.nextSibling ? o.insertBefore(i, t.nextSibling) : o.appendChild(i), i
            }
    
            function s(e) {
                var n;
                u(e) && i(e) && ("&nbsp;" != e.innerHTML ? e.removeAttribute("data-mce-caret") : e.parentNode && e.parentNode.removeChild(e)), d(e) && (n = t.trim(e.data), 0 === n.length && e.parentNode && e.parentNode.removeChild(e), e.nodeValue = n)
            }
    
            function l(e) {
                return d(e) && e.data[0] == t.ZWSP
            }
    
            function c(e) {
                return d(e) && e.data[e.data.length - 1] == t.ZWSP
            }
            var u = e.isElement,
                d = e.isText;
            return {
                isCaretContainer: i,
                isCaretContainerBlock: n,
                isCaretContainerInline: r,
                insertInline: o,
                insertBlock: a,
                remove: s,
                startsWithCaretContainer: l,
                endsWithCaretContainer: c
            }
        }), r(T, [m, y, _, k], function(e, t, n, r) {
            function i(e, t) {
                var n = e.childNodes;
                return t--, t > n.length - 1 ? t = n.length - 1 : 0 > t && (t = 0), n[t] || e
            }
    
            function o(e) {
                this.walk = function(t, n) {
                    function r(e) {
                        var t;
                        return t = e[0], 3 === t.nodeType && t === c && u >= t.nodeValue.length && e.splice(0, 1), t = e[e.length - 1], 0 === f && e.length > 0 && t === d && 3 === t.nodeType && e.splice(e.length - 1, 1), e
                    }
    
                    function o(e, t, n) {
                        for (var r = []; e && e != n; e = e[t]) r.push(e);
                        return r
                    }
    
                    function a(e, t) {
                        do {
                            if (e.parentNode == t) return e;
                            e = e.parentNode
                        } while (e)
                    }
    
                    function l(e, t, i) {
                        var a = i ? "nextSibling" : "previousSibling";
                        for (g = e, v = g.parentNode; g && g != t; g = v) v = g.parentNode, y = o(g == e ? g : g[a], a), y.length && (i || y.reverse(), n(r(y)))
                    }
                    var c = t.startContainer,
                        u = t.startOffset,
                        d = t.endContainer,
                        f = t.endOffset,
                        h, p, m, g, v, y, b;
                    if (b = e.select("td.mce-item-selected,th.mce-item-selected"), b.length > 0) return void s(b, function(e) {
                        n([e])
                    });
                    if (1 == c.nodeType && c.hasChildNodes() && (c = c.childNodes[u]), 1 == d.nodeType && d.hasChildNodes() && (d = i(d, f)), c == d) return n(r([c]));
                    for (h = e.findCommonAncestor(c, d), g = c; g; g = g.parentNode) {
                        if (g === d) return l(c, h, !0);
                        if (g === h) break
                    }
                    for (g = d; g; g = g.parentNode) {
                        if (g === c) return l(d, h);
                        if (g === h) break
                    }
                    p = a(c, h) || c, m = a(d, h) || d, l(c, p, !0), y = o(p == c ? p : p.nextSibling, "nextSibling", m == d ? m.nextSibling : m), y.length && n(r(y)), l(d, m)
                }, this.split = function(e) {
                    function t(e, t) {
                        return e.splitText(t)
                    }
                    var n = e.startContainer,
                        r = e.startOffset,
                        i = e.endContainer,
                        o = e.endOffset;
                    return n == i && 3 == n.nodeType ? r > 0 && r < n.nodeValue.length && (i = t(n, r), n = i.previousSibling, o > r ? (o -= r, n = i = t(i, o).previousSibling, o = i.nodeValue.length, r = 0) : o = 0) : (3 == n.nodeType && r > 0 && r < n.nodeValue.length && (n = t(n, r), r = 0), 3 == i.nodeType && o > 0 && o < i.nodeValue.length && (i = t(i, o).previousSibling, o = i.nodeValue.length)), {
                        startContainer: n,
                        startOffset: r,
                        endContainer: i,
                        endOffset: o
                    }
                }, this.normalize = function(n) {
                    function r(r) {
                        function a(e) {
                            return e && /^(TD|TH|CAPTION)$/.test(e.nodeName)
                        }
    
                        function s(n, r) {
                            for (var i = new t(n, e.getParent(n.parentNode, e.isBlock) || g); n = i[r ? "prev" : "next"]();)
                                if ("BR" === n.nodeName) return !0
                        }
    
                        function u(e) {
                            for (; e && e != g;) {
                                if (l(e)) return !0;
                                e = e.parentNode
                            }
                            return !1
                        }
    
                        function d(e, t) {
                            return e.previousSibling && e.previousSibling.nodeName == t
                        }
    
                        function f(n, r) {
                            var a, s, l;
                            if (r = r || h, l = e.getParent(r.parentNode, e.isBlock) || g, n && "BR" == r.nodeName && C && e.isEmpty(l)) return h = r.parentNode, p = e.nodeIndex(r), void(i = !0);
                            for (a = new t(r, l); v = a[n ? "prev" : "next"]();) {
                                if ("false" === e.getContentEditableParent(v) || c(v)) return;
                                if (3 === v.nodeType && v.nodeValue.length > 0) return h = v, p = n ? v.nodeValue.length : 0, void(i = !0);
                                if (e.isBlock(v) || y[v.nodeName.toLowerCase()]) return;
                                s = v
                            }
                            o && s && (h = s, i = !0, p = 0)
                        }
                        var h, p, m, g = e.getRoot(),
                            v, y, b, C;
                        if (h = n[(r ? "start" : "end") + "Container"], p = n[(r ? "start" : "end") + "Offset"], C = 1 == h.nodeType && p === h.childNodes.length, y = e.schema.getNonEmptyElements(), b = r, !c(h)) {
                            if (1 == h.nodeType && p > h.childNodes.length - 1 && (b = !1), 9 === h.nodeType && (h = e.getRoot(), p = 0), h === g) {
                                if (b && (v = h.childNodes[p > 0 ? p - 1 : 0])) {
                                    if (c(v)) return;
                                    if (y[v.nodeName] || "TABLE" == v.nodeName) return
                                }
                                if (h.hasChildNodes()) {
                                    if (p = Math.min(!b && p > 0 ? p - 1 : p, h.childNodes.length - 1), h = h.childNodes[p], p = 0, u(h) || c(h)) return;
                                    if (h.hasChildNodes() && !/TABLE/.test(h.nodeName)) {
                                        v = h, m = new t(h, g);
                                        do {
                                            if (l(v) || c(v)) {
                                                i = !1;
                                                break
                                            }
                                            if (3 === v.nodeType && v.nodeValue.length > 0) {
                                                p = b ? 0 : v.nodeValue.length, h = v, i = !0;
                                                break
                                            }
                                            if (y[v.nodeName.toLowerCase()] && !a(v)) {
                                                p = e.nodeIndex(v), h = v.parentNode, "IMG" != v.nodeName || b || p++, i = !0;
                                                break
                                            }
                                        } while (v = b ? m.next() : m.prev())
                                    }
                                }
                            }
                            o && (3 === h.nodeType && 0 === p && f(!0), 1 === h.nodeType && (v = h.childNodes[p], v || (v = h.childNodes[p - 1]), !v || "BR" !== v.nodeName || d(v, "A") || s(v) || s(v, !0) || f(!0, v))), b && !o && 3 === h.nodeType && p === h.nodeValue.length && f(!1), i && n["set" + (r ? "Start" : "End")](h, p)
                        }
                    }
                    var i, o;
                    return o = n.collapsed, r(!0), o || r(), i && o && n.collapse(!0), i
                }
            }
    
            function a(t, n, r) {
                var i, o, a;
                if (i = r.elementFromPoint(t, n), o = r.body.createTextRange(), "HTML" == i.tagName && (i = r.body), o.moveToElementText(i), a = e.toArray(o.getClientRects()), a = a.sort(function(e, t) {
                        return e = Math.abs(Math.max(e.top - n, e.bottom - n)), t = Math.abs(Math.max(t.top - n, t.bottom - n)), e - t
                    }), a.length > 0) {
                    n = (a[0].bottom + a[0].top) / 2;
                    try {
                        return o.moveToPoint(t, n), o.collapse(!0), o
                    } catch (s) {}
                }
                return null
            }
            var s = e.each,
                l = n.isContentEditableFalse,
                c = r.isCaretContainer;
            return o.compareRanges = function(e, t) {
                if (e && t) {
                    if (!e.item && !e.duplicate) return e.startContainer == t.startContainer && e.startOffset == t.startOffset;
                    if (e.item && t.item && e.item(0) === t.item(0)) return !0;
                    if (e.isEqual && t.isEqual && t.isEqual(e)) return !0
                }
                return !1
            }, o.getCaretRangeFromPoint = function(e, t, n) {
                var r, i;
                if (n.caretPositionFromPoint) i = n.caretPositionFromPoint(e, t), r = n.createRange(), r.setStart(i.offsetNode, i.offset), r.collapse(!0);
                else if (n.caretRangeFromPoint) r = n.caretRangeFromPoint(e, t);
                else if (n.body.createTextRange) {
                    r = n.body.createTextRange();
                    try {
                        r.moveToPoint(e, t), r.collapse(!0)
                    } catch (o) {
                        r = a(e, t, n)
                    }
                }
                return r
            }, o.getSelectedNode = function(e) {
                var t = e.startContainer,
                    n = e.startOffset;
                return t.hasChildNodes() && e.endOffset == n + 1 ? t.childNodes[n] : null
            }, o.getNode = function(e, t) {
                return 1 == e.nodeType && e.hasChildNodes() && (t >= e.childNodes.length && (t = e.childNodes.length - 1), e = e.childNodes[t]), e
            }, o
        }), r(R, [T, h, u], function(e, t, n) {
            return function(r) {
                function i(e) {
                    var t, n;
                    if (n = r.$(e).parentsUntil(r.getBody()).add(e), n.length === a.length) {
                        for (t = n.length; t >= 0 && n[t] === a[t]; t--);
                        if (-1 === t) return a = n, !0
                    }
                    return a = n, !1
                }
                var o, a = [];
                "onselectionchange" in r.getDoc() || r.on("NodeChange Click MouseUp KeyUp Focus", function(t) {
                    var n, i;
                    n = r.selection.getRng(), i = {
                        startContainer: n.startContainer,
                        startOffset: n.startOffset,
                        endContainer: n.endContainer,
                        endOffset: n.endOffset
                    }, "nodechange" != t.type && e.compareRanges(i, o) || r.fire("SelectionChange"), o = i
                }), r.on("contextmenu", function() {
                    r.fire("SelectionChange")
                }), r.on("SelectionChange", function() {
                    var e = r.selection.getStart(!0);
                    (t.range || !r.selection.isCollapsed()) && !i(e) && r.dom.isChildOf(e, r.getBody()) && r.nodeChanged({
                        selectionChange: !0
                    })
                }), r.on("MouseUp", function(e) {
                    e.isDefaultPrevented() || ("IMG" == r.selection.getNode().nodeName ? n.setEditorTimeout(r, function() {
                        r.nodeChanged()
                    }) : r.nodeChanged())
                }), this.nodeChanged = function(e) {
                    var t = r.selection,
                        n, i, o;
                    r.initialized && t && !r.settings.disable_nodechange && !r.readonly && (o = r.getBody(), n = t.getStart() || o, n = n.ownerDocument != r.getDoc() ? r.getBody() : n, "IMG" == n.nodeName && t.isCollapsed() && (n = n.parentNode), i = [], r.dom.getParent(n, function(e) {
                        return e === o ? !0 : void i.push(e)
                    }), e = e || {}, e.element = n, e.parents = i, r.fire("NodeChange", e))
                }
            }
        }), r(A, [], function() {
            function e(e, t, n) {
                var r, i, o = n ? "lastChild" : "firstChild",
                    a = n ? "prev" : "next";
                if (e[o]) return e[o];
                if (e !== t) {
                    if (r = e[a]) return r;
                    for (i = e.parent; i && i !== t; i = i.parent)
                        if (r = i[a]) return r
                }
            }
    
            function t(e, t) {
                this.name = e, this.type = t, 1 === t && (this.attributes = [], this.attributes.map = {})
            }
            var n = /^[ \t\r\n]*$/,
                r = {
                    "#text": 3,
                    "#comment": 8,
                    "#cdata": 4,
                    "#pi": 7,
                    "#doctype": 10,
                    "#document-fragment": 11
                };
            return t.prototype = {
                replace: function(e) {
                    var t = this;
                    return e.parent && e.remove(), t.insert(e, t), t.remove(), t
                },
                attr: function(e, t) {
                    var n = this,
                        r, i, o;
                    if ("string" != typeof e) {
                        for (i in e) n.attr(i, e[i]);
                        return n
                    }
                    if (r = n.attributes) {
                        if (t !== o) {
                            if (null === t) {
                                if (e in r.map)
                                    for (delete r.map[e], i = r.length; i--;)
                                        if (r[i].name === e) return r = r.splice(i, 1), n;
                                return n
                            }
                            if (e in r.map) {
                                for (i = r.length; i--;)
                                    if (r[i].name === e) {
                                        r[i].value = t;
                                        break
                                    }
                            } else r.push({
                                name: e,
                                value: t
                            });
                            return r.map[e] = t, n
                        }
                        return r.map[e]
                    }
                },
                clone: function() {
                    var e = this,
                        n = new t(e.name, e.type),
                        r, i, o, a, s;
                    if (o = e.attributes) {
                        for (s = [], s.map = {}, r = 0, i = o.length; i > r; r++) a = o[r], "id" !== a.name && (s[s.length] = {
                            name: a.name,
                            value: a.value
                        }, s.map[a.name] = a.value);
                        n.attributes = s
                    }
                    return n.value = e.value, n.shortEnded = e.shortEnded, n
                },
                wrap: function(e) {
                    var t = this;
                    return t.parent.insert(e, t), e.append(t), t
                },
                unwrap: function() {
                    var e = this,
                        t, n;
                    for (t = e.firstChild; t;) n = t.next, e.insert(t, e, !0), t = n;
                    e.remove()
                },
                remove: function() {
                    var e = this,
                        t = e.parent,
                        n = e.next,
                        r = e.prev;
                    return t && (t.firstChild === e ? (t.firstChild = n, n && (n.prev = null)) : r.next = n, t.lastChild === e ? (t.lastChild = r, r && (r.next = null)) : n.prev = r, e.parent = e.next = e.prev = null), e
                },
                append: function(e) {
                    var t = this,
                        n;
                    return e.parent && e.remove(), n = t.lastChild, n ? (n.next = e, e.prev = n, t.lastChild = e) : t.lastChild = t.firstChild = e, e.parent = t, e
                },
                insert: function(e, t, n) {
                    var r;
                    return e.parent && e.remove(), r = t.parent || this, n ? (t === r.firstChild ? r.firstChild = e : t.prev.next = e, e.prev = t.prev, e.next = t, t.prev = e) : (t === r.lastChild ? r.lastChild = e : t.next.prev = e, e.next = t.next, e.prev = t, t.next = e), e.parent = r, e
                },
                getAll: function(t) {
                    var n = this,
                        r, i = [];
                    for (r = n.firstChild; r; r = e(r, n)) r.name === t && i.push(r);
                    return i
                },
                empty: function() {
                    var t = this,
                        n, r, i;
                    if (t.firstChild) {
                        for (n = [], i = t.firstChild; i; i = e(i, t)) n.push(i);
                        for (r = n.length; r--;) i = n[r], i.parent = i.firstChild = i.lastChild = i.next = i.prev = null
                    }
                    return t.firstChild = t.lastChild = null, t
                },
                isEmpty: function(t) {
                    var r = this,
                        i = r.firstChild,
                        o, a;
                    if (i)
                        do {
                            if (1 === i.type) {
                                if (i.attributes.map["data-mce-bogus"]) continue;
                                if (t[i.name]) return !1;
                                for (o = i.attributes.length; o--;)
                                    if (a = i.attributes[o].name, "name" === a || 0 === a.indexOf("data-mce-bookmark")) return !1
                            }
                            if (8 === i.type) return !1;
                            if (3 === i.type && !n.test(i.value)) return !1
                        } while (i = e(i, r));
                    return !0
                },
                walk: function(t) {
                    return e(this, null, t)
                }
            }, t.create = function(e, n) {
                var i, o;
                if (i = new t(e, r[e] || 1), n)
                    for (o in n) i.attr(o, n[o]);
                return i
            }, t
        }), r(B, [m], function(e) {
            function t(e, t) {
                return e ? e.split(t || " ") : []
            }
    
            function n(e) {
                function n(e, n, r) {
                    function i(e, t) {
                        var n = {},
                            r, i;
                        for (r = 0, i = e.length; i > r; r++) n[e[r]] = t || {};
                        return n
                    }
                    var s, c, u, d = arguments;
                    for (r = r || [], n = n || "", "string" == typeof r && (r = t(r)), c = 3; c < d.length; c++) "string" == typeof d[c] && (d[c] = t(d[c])), r.push.apply(r, d[c]);
                    for (e = t(e), s = e.length; s--;) u = [].concat(l, t(n)), a[e[s]] = {
                        attributes: i(u),
                        attributesOrder: u,
                        children: i(r, o)
                    }
                }
    
                function r(e, n) {
                    var r, i, o, s;
                    for (e = t(e), r = e.length, n = t(n); r--;)
                        for (i = a[e[r]], o = 0, s = n.length; s > o; o++) i.attributes[n[o]] = {}, i.attributesOrder.push(n[o])
                }
                var a = {},
                    l, c, u, d, f, h;
                return i[e] ? i[e] : (l = t("id accesskey class dir lang style tabindex title"), c = t("address blockquote div dl fieldset form h1 h2 h3 h4 h5 h6 hr menu ol p pre table ul"), u = t("a abbr b bdo br button cite code del dfn em embed i iframe img input ins kbd label map noscript object q s samp script select small span strong sub sup textarea u var #text #comment"), "html4" != e && (l.push.apply(l, t("contenteditable contextmenu draggable dropzone hidden spellcheck translate")), c.push.apply(c, t("article aside details dialog figure header footer hgroup section nav")), u.push.apply(u, t("audio canvas command datalist mark meter output picture progress time wbr video ruby bdi keygen"))), "html5-strict" != e && (l.push("xml:lang"), h = t("acronym applet basefont big font strike tt"), u.push.apply(u, h), s(h, function(e) {
                    n(e, "", u)
                }), f = t("center dir isindex noframes"), c.push.apply(c, f), d = [].concat(c, u), s(f, function(e) {
                    n(e, "", d)
                })), d = d || [].concat(c, u), n("html", "manifest", "head body"), n("head", "", "base command link meta noscript script style title"), n("title hr noscript br"), n("base", "href target"), n("link", "href rel media hreflang type sizes hreflang"), n("meta", "name http-equiv content charset"), n("style", "media type scoped"), n("script", "src async defer type charset"), n("body", "onafterprint onbeforeprint onbeforeunload onblur onerror onfocus onhashchange onload onmessage onoffline ononline onpagehide onpageshow onpopstate onresize onscroll onstorage onunload", d), n("address dt dd div caption", "", d), n("h1 h2 h3 h4 h5 h6 pre p abbr code var samp kbd sub sup i b u bdo span legend em strong small s cite dfn", "", u), n("blockquote", "cite", d), n("ol", "reversed start type", "li"), n("ul", "", "li"), n("li", "value", d), n("dl", "", "dt dd"), n("a", "href target rel media hreflang type", u), n("q", "cite", u), n("ins del", "cite datetime", d), n("img", "src sizes srcset alt usemap ismap width height"), n("iframe", "src name width height", d), n("embed", "src type width height"), n("object", "data type typemustmatch name usemap form width height", d, "param"), n("param", "name value"), n("map", "name", d, "area"), n("area", "alt coords shape href target rel media hreflang type"), n("table", "border", "caption colgroup thead tfoot tbody tr" + ("html4" == e ? " col" : "")), n("colgroup", "span", "col"), n("col", "span"), n("tbody thead tfoot", "", "tr"), n("tr", "", "td th"), n("td", "colspan rowspan headers", d), n("th", "colspan rowspan headers scope abbr", d), n("form", "accept-charset action autocomplete enctype method name novalidate target", d), n("fieldset", "disabled form name", d, "legend"), n("label", "form for", u), n("input", "accept alt autocomplete checked dirname disabled form formaction formenctype formmethod formnovalidate formtarget height list max maxlength min multiple name pattern readonly required size src step type value width"), n("button", "disabled form formaction formenctype formmethod formnovalidate formtarget name type value", "html4" == e ? d : u), n("select", "disabled form multiple name required size", "option optgroup"), n("optgroup", "disabled label", "option"), n("option", "disabled label selected value"), n("textarea", "cols dirname disabled form maxlength name readonly required rows wrap"), n("menu", "type label", d, "li"), n("noscript", "", d), "html4" != e && (n("wbr"), n("ruby", "", u, "rt rp"), n("figcaption", "", d), n("mark rt rp summary bdi", "", u), n("canvas", "width height", d), n("video", "src crossorigin poster preload autoplay mediagroup loop muted controls width height buffered", d, "track source"), n("audio", "src crossorigin preload autoplay mediagroup loop muted controls buffered volume", d, "track source"), n("picture", "", "img source"), n("source", "src srcset type media sizes"), n("track", "kind src srclang label default"), n("datalist", "", u, "option"), n("article section nav aside header footer", "", d), n("hgroup", "", "h1 h2 h3 h4 h5 h6"), n("figure", "", d, "figcaption"), n("time", "datetime", u), n("dialog", "open", d), n("command", "type label icon disabled checked radiogroup command"), n("output", "for form name", u), n("progress", "value max", u), n("meter", "value min max low high optimum", u), n("details", "open", d, "summary"), n("keygen", "autofocus challenge disabled form keytype name")), "html5-strict" != e && (r("script", "language xml:space"), r("style", "xml:space"), r("object", "declare classid code codebase codetype archive standby align border hspace vspace"), r("embed", "align name hspace vspace"), r("param", "valuetype type"), r("a", "charset name rev shape coords"), r("br", "clear"), r("applet", "codebase archive code object alt name width height align hspace vspace"), r("img", "name longdesc align border hspace vspace"), r("iframe", "longdesc frameborder marginwidth marginheight scrolling align"), r("font basefont", "size color face"), r("input", "usemap align"), r("select", "onchange"), r("textarea"), r("h1 h2 h3 h4 h5 h6 div p legend caption", "align"), r("ul", "type compact"), r("li", "type"), r("ol dl menu dir", "compact"), r("pre", "width xml:space"), r("hr", "align noshade size width"), r("isindex", "prompt"), r("table", "summary width frame rules cellspacing cellpadding align bgcolor"), r("col", "width align char charoff valign"), r("colgroup", "width align char charoff valign"), r("thead", "align char charoff valign"), r("tr", "align char charoff valign bgcolor"), r("th", "axis align char charoff valign nowrap bgcolor width height"), r("form", "accept"), r("td", "abbr axis scope align char charoff valign nowrap bgcolor width height"), r("tfoot", "align char charoff valign"), r("tbody", "align char charoff valign"), r("area", "nohref"), r("body", "background bgcolor text link vlink alink")), "html4" != e && (r("input button select textarea", "autofocus"), r("input textarea", "placeholder"), r("a", "download"), r("link script img", "crossorigin"), r("iframe", "sandbox seamless allowfullscreen")), s(t("a form meter progress dfn"), function(e) {
                    a[e] && delete a[e].children[e]
                }), delete a.caption.children.table, delete a.script, i[e] = a, a)
            }
    
            function r(e, t) {
                var n;
                return e && (n = {}, "string" == typeof e && (e = {
                    "*": e
                }), s(e, function(e, r) {
                    n[r] = n[r.toUpperCase()] = "map" == t ? a(e, /[, ]/) : c(e, /[, ]/)
                })), n
            }
            var i = {},
                o = {},
                a = e.makeMap,
                s = e.each,
                l = e.extend,
                c = e.explode,
                u = e.inArray;
            return function(e) {
                function o(t, n, r) {
                    var o = e[t];
                    return o ? o = a(o, /[, ]/, a(o.toUpperCase(), /[, ]/)) : (o = i[t], o || (o = a(n, " ", a(n.toUpperCase(), " ")), o = l(o, r), i[t] = o)), o
                }
    
                function d(e) {
                    return new RegExp("^" + e.replace(/([?+*])/g, ".$1") + "$")
                }
    
                function f(e) {
                    var n, r, i, o, s, l, c, f, h, p, m, g, v, b, x, w, E, N, _, S = /^([#+\-])?([^\[!\/]+)(?:\/([^\[!]+))?(?:(!?)\[([^\]]+)\])?$/,
                        k = /^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/,
                        T = /[*?+]/;
                    if (e)
                        for (e = t(e, ","), y["@"] && (w = y["@"].attributes, E = y["@"].attributesOrder), n = 0, r = e.length; r > n; n++)
                            if (s = S.exec(e[n])) {
                                if (b = s[1], h = s[2], x = s[3], f = s[5], g = {}, v = [], l = {
                                        attributes: g,
                                        attributesOrder: v
                                    }, "#" === b && (l.paddEmpty = !0), "-" === b && (l.removeEmpty = !0), "!" === s[4] && (l.removeEmptyAttrs = !0), w) {
                                    for (N in w) g[N] = w[N];
                                    v.push.apply(v, E)
                                }
                                if (f)
                                    for (f = t(f, "|"), i = 0, o = f.length; o > i; i++)
                                        if (s = k.exec(f[i])) {
                                            if (c = {}, m = s[1], p = s[2].replace(/::/g, ":"), b = s[3], _ = s[4], "!" === m && (l.attributesRequired = l.attributesRequired || [], l.attributesRequired.push(p), c.required = !0), "-" === m) {
                                                delete g[p], v.splice(u(v, p), 1);
                                                continue
                                            }
                                            b && ("=" === b && (l.attributesDefault = l.attributesDefault || [], l.attributesDefault.push({
                                                name: p,
                                                value: _
                                            }), c.defaultValue = _), ":" === b && (l.attributesForced = l.attributesForced || [], l.attributesForced.push({
                                                name: p,
                                                value: _
                                            }), c.forcedValue = _), "<" === b && (c.validValues = a(_, "?"))), T.test(p) ? (l.attributePatterns = l.attributePatterns || [], c.pattern = d(p), l.attributePatterns.push(c)) : (g[p] || v.push(p), g[p] = c)
                                        }
                                w || "@" != h || (w = g, E = v), x && (l.outputName = h, y[x] = l), T.test(h) ? (l.pattern = d(h), C.push(l)) : y[h] = l
                            }
                }
    
                function h(e) {
                    y = {}, C = [], f(e), s(E, function(e, t) {
                        b[t] = e.children
                    })
                }
    
                function p(e) {
                    var n = /^(~)?(.+)$/;
                    e && (i.text_block_elements = i.block_elements = null, s(t(e, ","), function(e) {
                        var t = n.exec(e),
                            r = "~" === t[1],
                            i = r ? "span" : "div",
                            o = t[2];
                        if (b[o] = b[i], L[o] = i, r || (R[o.toUpperCase()] = {}, R[o] = {}), !y[o]) {
                            var a = y[i];
                            a = l({}, a), delete a.removeEmptyAttrs, delete a.removeEmpty, y[o] = a
                        }
                        s(b, function(e, t) {
                            e[i] && (b[t] = e = l({}, b[t]), e[o] = e[i])
                        })
                    }))
                }
    
                function m(n) {
                    var r = /^([+\-]?)(\w+)\[([^\]]+)\]$/;
                    i[e.schema] = null, n && s(t(n, ","), function(e) {
                        var n = r.exec(e),
                            i, o;
                        n && (o = n[1], i = o ? b[n[2]] : b[n[2]] = {
                            "#comment": {}
                        }, i = b[n[2]], s(t(n[3], "|"), function(e) {
                            "-" === o ? delete i[e] : i[e] = {}
                        }))
                    })
                }
    
                function g(e) {
                    var t = y[e],
                        n;
                    if (t) return t;
                    for (n = C.length; n--;)
                        if (t = C[n], t.pattern.test(e)) return t
                }
                var v = this,
                    y = {},
                    b = {},
                    C = [],
                    x, w, E, N, _, S, k, T, R, A, B, D, M, L = {},
                    P = {};
                e = e || {}, E = n(e.schema), e.verify_html === !1 && (e.valid_elements = "*[*]"),
                    x = r(e.valid_styles), w = r(e.invalid_styles, "map"), T = r(e.valid_classes, "map"), N = o("whitespace_elements", "pre script noscript style textarea video audio iframe object"), _ = o("self_closing_elements", "colgroup dd dt li option p td tfoot th thead tr"), S = o("short_ended_elements", "area base basefont br col frame hr img input isindex link meta param embed source wbr track"), k = o("boolean_attributes", "checked compact declare defer disabled ismap multiple nohref noresize noshade nowrap readonly selected autoplay loop controls"), A = o("non_empty_elements", "td th iframe video audio object script", S), B = o("move_caret_before_on_enter_elements", "table", A), D = o("text_block_elements", "h1 h2 h3 h4 h5 h6 p div address pre form blockquote center dir fieldset header footer article section hgroup aside nav figure"), R = o("block_elements", "hr table tbody thead tfoot th tr td li ol ul caption dl dt dd noscript menu isindex option datalist select optgroup figcaption", D), M = o("text_inline_elements", "span strong b em i font strike u var cite dfn code mark q sup sub samp"), s((e.special || "script noscript style textarea").split(" "), function(e) {
                        P[e] = new RegExp("</" + e + "[^>]*>", "gi")
                    }), e.valid_elements ? h(e.valid_elements) : (s(E, function(e, t) {
                        y[t] = {
                            attributes: e.attributes,
                            attributesOrder: e.attributesOrder
                        }, b[t] = e.children
                    }), "html5" != e.schema && s(t("strong/b em/i"), function(e) {
                        e = t(e, "/"), y[e[1]].outputName = e[0]
                    }), y.img.attributesDefault = [{
                        name: "alt",
                        value: ""
                    }], s(t("ol ul sub sup blockquote span font a table tbody tr strong em b i"), function(e) {
                        y[e] && (y[e].removeEmpty = !0)
                    }), s(t("p h1 h2 h3 h4 h5 h6 th td pre div address caption"), function(e) {
                        y[e].paddEmpty = !0
                    }), s(t("span"), function(e) {
                        y[e].removeEmptyAttrs = !0
                    })), p(e.custom_elements), m(e.valid_children), f(e.extended_valid_elements), m("+ol[ul|ol],+ul[ul|ol]"), e.invalid_elements && s(c(e.invalid_elements), function(e) {
                        y[e] && delete y[e]
                    }), g("span") || f("span[!data-mce-type|*]"), v.children = b, v.getValidStyles = function() {
                        return x
                    }, v.getInvalidStyles = function() {
                        return w
                    }, v.getValidClasses = function() {
                        return T
                    }, v.getBoolAttrs = function() {
                        return k
                    }, v.getBlockElements = function() {
                        return R
                    }, v.getTextBlockElements = function() {
                        return D
                    }, v.getTextInlineElements = function() {
                        return M
                    }, v.getShortEndedElements = function() {
                        return S
                    }, v.getSelfClosingElements = function() {
                        return _
                    }, v.getNonEmptyElements = function() {
                        return A
                    }, v.getMoveCaretBeforeOnEnterElements = function() {
                        return B
                    }, v.getWhiteSpaceElements = function() {
                        return N
                    }, v.getSpecialElements = function() {
                        return P
                    }, v.isValidChild = function(e, t) {
                        var n = b[e];
                        return !(!n || !n[t])
                    }, v.isValid = function(e, t) {
                        var n, r, i = g(e);
                        if (i) {
                            if (!t) return !0;
                            if (i.attributes[t]) return !0;
                            if (n = i.attributePatterns)
                                for (r = n.length; r--;)
                                    if (n[r].pattern.test(e)) return !0
                        }
                        return !1
                    }, v.getElementRule = g, v.getCustomElements = function() {
                        return L
                    }, v.addValidElements = f, v.setValidElements = h, v.addCustomElements = p, v.addValidChildren = m, v.elements = y
            }
        }), r(D, [B, C, m], function(e, t, n) {
            function r(e, t, n) {
                var r = 1,
                    i, o, a, s;
                for (s = e.getShortEndedElements(), a = /<([!?\/])?([A-Za-z0-9\-_\:\.]+)((?:\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\/|\s+)>/g, a.lastIndex = i = n; o = a.exec(t);) {
                    if (i = a.lastIndex, "/" === o[1]) r--;
                    else if (!o[1]) {
                        if (o[2] in s) continue;
                        r++
                    }
                    if (0 === r) break
                }
                return i
            }
    
            function i(i, a) {
                function s() {}
                var l = this;
                i = i || {}, l.schema = a = a || new e, i.fix_self_closing !== !1 && (i.fix_self_closing = !0), o("comment cdata text start end pi doctype".split(" "), function(e) {
                    e && (l[e] = i[e] || s)
                }), l.parse = function(e) {
                    function o(e) {
                        var t, n;
                        for (t = h.length; t-- && h[t].name !== e;);
                        if (t >= 0) {
                            for (n = h.length - 1; n >= t; n--) e = h[n], e.valid && l.end(e.name);
                            h.length = t
                        }
                    }
    
                    function s(e, t, n, r, o) {
                        var a, s, l = /[\s\u0000-\u001F]+/g;
                        if (t = t.toLowerCase(), n = t in x ? t : z(n || r || o || ""), E && !y && 0 !== t.indexOf("data-")) {
                            if (a = T[t], !a && R) {
                                for (s = R.length; s-- && (a = R[s], !a.pattern.test(t));); - 1 === s && (a = null)
                            }
                            if (!a) return;
                            if (a.validValues && !(n in a.validValues)) return
                        }
                        if (V[t] && !i.allow_script_urls) {
                            var c = n.replace(l, "");
                            try {
                                c = decodeURIComponent(c)
                            } catch (u) {
                                c = unescape(c)
                            }
                            if (U.test(c)) return;
                            if (!i.allow_html_data_urls && $.test(c) && !/^data:image\//i.test(c)) return
                        }
                        p.map[t] = n, p.push({
                            name: t,
                            value: n
                        })
                    }
                    var l = this,
                        c, u = 0,
                        d, f, h = [],
                        p, m, g, v, y, b, C, x, w, E, N, _, S, k, T, R, A, B, D, M, L, P, H, O, I, F = 0,
                        z = t.decode,
                        W, V = n.makeMap("src,href,data,background,formaction,poster"),
                        U = /((java|vb)script|mhtml):/i,
                        $ = /^data:/i;
                    for (P = new RegExp("<(?:(?:!--([\\w\\W]*?)-->)|(?:!\\[CDATA\\[([\\w\\W]*?)\\]\\]>)|(?:!DOCTYPE([\\w\\W]*?)>)|(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|(?:\\/([^>]+)>)|(?:([A-Za-z0-9\\-_\\:\\.]+)((?:\\s+[^\"'>]+(?:(?:\"[^\"]*\")|(?:'[^']*')|[^>]*))*|\\/|\\s+)>))", "g"), H = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:[^\"])*)\")|(?:\'((?:[^\'])*)\')|([^>\s]+)))?/g, C = a.getShortEndedElements(), L = i.self_closing_elements || a.getSelfClosingElements(), x = a.getBoolAttrs(), E = i.validate, b = i.remove_internals, W = i.fix_self_closing, O = a.getSpecialElements(); c = P.exec(e);) {
                        if (u < c.index && l.text(z(e.substr(u, c.index - u))), d = c[6]) d = d.toLowerCase(), ":" === d.charAt(0) && (d = d.substr(1)), o(d);
                        else if (d = c[7]) {
                            if (d = d.toLowerCase(), ":" === d.charAt(0) && (d = d.substr(1)), w = d in C, W && L[d] && h.length > 0 && h[h.length - 1].name === d && o(d), !E || (N = a.getElementRule(d))) {
                                if (_ = !0, E && (T = N.attributes, R = N.attributePatterns), (k = c[8]) ? (y = -1 !== k.indexOf("data-mce-type"), y && b && (_ = !1), p = [], p.map = {}, k.replace(H, s)) : (p = [], p.map = {}), E && !y) {
                                    if (A = N.attributesRequired, B = N.attributesDefault, D = N.attributesForced, M = N.removeEmptyAttrs, M && !p.length && (_ = !1), D)
                                        for (m = D.length; m--;) S = D[m], v = S.name, I = S.value, "{$uid}" === I && (I = "mce_" + F++), p.map[v] = I, p.push({
                                            name: v,
                                            value: I
                                        });
                                    if (B)
                                        for (m = B.length; m--;) S = B[m], v = S.name, v in p.map || (I = S.value, "{$uid}" === I && (I = "mce_" + F++), p.map[v] = I, p.push({
                                            name: v,
                                            value: I
                                        }));
                                    if (A) {
                                        for (m = A.length; m-- && !(A[m] in p.map);); - 1 === m && (_ = !1)
                                    }
                                    if (S = p.map["data-mce-bogus"]) {
                                        if ("all" === S) {
                                            u = r(a, e, P.lastIndex), P.lastIndex = u;
                                            continue
                                        }
                                        _ = !1
                                    }
                                }
                                _ && l.start(d, p, w)
                            } else _ = !1;
                            if (f = O[d]) {
                                f.lastIndex = u = c.index + c[0].length, (c = f.exec(e)) ? (_ && (g = e.substr(u, c.index - u)), u = c.index + c[0].length) : (g = e.substr(u), u = e.length), _ && (g.length > 0 && l.text(g, !0), l.end(d)), P.lastIndex = u;
                                continue
                            }
                            w || (k && k.indexOf("/") == k.length - 1 ? _ && l.end(d) : h.push({
                                name: d,
                                valid: _
                            }))
                        } else(d = c[1]) ? (">" === d.charAt(0) && (d = " " + d), i.allow_conditional_comments || "[if" !== d.substr(0, 3) || (d = " " + d), l.comment(d)) : (d = c[2]) ? l.cdata(d) : (d = c[3]) ? l.doctype(d) : (d = c[4]) && l.pi(d, c[5]);
                        u = c.index + c[0].length
                    }
                    for (u < e.length && l.text(z(e.substr(u))), m = h.length - 1; m >= 0; m--) d = h[m], d.valid && l.end(d.name)
                }
            }
            var o = n.each;
            return i.findEndTag = r, i
        }), r(M, [A, B, D, m], function(e, t, n, r) {
            var i = r.makeMap,
                o = r.each,
                a = r.explode,
                s = r.extend;
            return function(r, l) {
                function c(t) {
                    var n, r, o, a, s, c, d, f, h, p, m, g, v, y, b;
                    for (m = i("tr,td,th,tbody,thead,tfoot,table"), p = l.getNonEmptyElements(), g = l.getTextBlockElements(), v = l.getSpecialElements(), n = 0; n < t.length; n++)
                        if (r = t[n], r.parent && !r.fixed)
                            if (g[r.name] && "li" == r.parent.name) {
                                for (y = r.next; y && g[y.name];) y.name = "li", y.fixed = !0, r.parent.insert(y, r.parent), y = y.next;
                                r.unwrap(r)
                            } else {
                                for (a = [r], o = r.parent; o && !l.isValidChild(o.name, r.name) && !m[o.name]; o = o.parent) a.push(o);
                                if (o && a.length > 1) {
                                    for (a.reverse(), s = c = u.filterNode(a[0].clone()), h = 0; h < a.length - 1; h++) {
                                        for (l.isValidChild(c.name, a[h].name) ? (d = u.filterNode(a[h].clone()), c.append(d)) : d = c, f = a[h].firstChild; f && f != a[h + 1];) b = f.next, d.append(f), f = b;
                                        c = d
                                    }
                                    s.isEmpty(p) ? o.insert(r, a[0], !0) : (o.insert(s, a[0], !0), o.insert(r, s)), o = a[0], (o.isEmpty(p) || o.firstChild === o.lastChild && "br" === o.firstChild.name) && o.empty().remove()
                                } else if (r.parent) {
                                    if ("li" === r.name) {
                                        if (y = r.prev, y && ("ul" === y.name || "ul" === y.name)) {
                                            y.append(r);
                                            continue
                                        }
                                        if (y = r.next, y && ("ul" === y.name || "ul" === y.name)) {
                                            y.insert(r, y.firstChild, !0);
                                            continue
                                        }
                                        r.wrap(u.filterNode(new e("ul", 1)));
                                        continue
                                    }
                                    l.isValidChild(r.parent.name, "div") && l.isValidChild("div", r.name) ? r.wrap(u.filterNode(new e("div", 1))) : v[r.name] ? r.empty().remove() : r.unwrap()
                                }
                            }
                }
                var u = this,
                    d = {},
                    f = [],
                    h = {},
                    p = {};
                r = r || {}, r.validate = "validate" in r ? r.validate : !0, r.root_name = r.root_name || "body", u.schema = l = l || new t, u.filterNode = function(e) {
                    var t, n, r;
                    n in d && (r = h[n], r ? r.push(e) : h[n] = [e]), t = f.length;
                    for (; t--;) n = f[t].name, n in e.attributes.map && (r = p[n], r ? r.push(e) : p[n] = [e]);
                    return e
                }, u.addNodeFilter = function(e, t) {
                    o(a(e), function(e) {
                        var n = d[e];
                        n || (d[e] = n = []), n.push(t)
                    })
                }, u.addAttributeFilter = function(e, t) {
                    o(a(e), function(e) {
                        var n;
                        for (n = 0; n < f.length; n++)
                            if (f[n].name === e) return void f[n].callbacks.push(t);
                        f.push({
                            name: e,
                            callbacks: [t]
                        })
                    })
                }, u.parse = function(t, o) {
                    function a() {
                        function e(e) {
                            e && (t = e.firstChild, t && 3 == t.type && (t.value = t.value.replace(R, "")), t = e.lastChild, t && 3 == t.type && (t.value = t.value.replace(D, "")))
                        }
                        var t = y.firstChild,
                            n, i;
                        if (l.isValidChild(y.name, I.toLowerCase())) {
                            for (; t;) n = t.next, 3 == t.type || 1 == t.type && "p" !== t.name && !T[t.name] && !t.attr("data-mce-type") ? i ? i.append(t) : (i = u(I, 1), i.attr(r.forced_root_block_attrs), y.insert(i, t), i.append(t)) : (e(i), i = null), t = n;
                            e(i)
                        }
                    }
    
                    function u(t, n) {
                        var r = new e(t, n),
                            i;
                        return t in d && (i = h[t], i ? i.push(r) : h[t] = [r]), r
                    }
    
                    function m(e) {
                        var t, n, r, i, o = l.getBlockElements();
                        for (t = e.prev; t && 3 === t.type;) {
                            if (r = t.value.replace(D, ""), r.length > 0) return void(t.value = r);
                            if (n = t.next) {
                                if (3 == n.type && n.value.length) {
                                    t = t.prev;
                                    continue
                                }
                                if (!o[n.name] && "script" != n.name && "style" != n.name) {
                                    t = t.prev;
                                    continue
                                }
                            }
                            i = t.prev, t.remove(), t = i
                        }
                    }
    
                    function g(e) {
                        var t, n = {};
                        for (t in e) "li" !== t && "p" != t && (n[t] = e[t]);
                        return n
                    }
                    var v, y, b, C, x, w, E, N, _, S, k, T, R, A = [],
                        B, D, M, L, P, H, O, I;
                    if (o = o || {}, h = {}, p = {}, T = s(i("script,style,head,html,body,title,meta,param"), l.getBlockElements()), O = l.getNonEmptyElements(), H = l.children, k = r.validate, I = "forced_root_block" in o ? o.forced_root_block : r.forced_root_block, P = l.getWhiteSpaceElements(), R = /^[ \t\r\n]+/, D = /[ \t\r\n]+$/, M = /[ \t\r\n]+/g, L = /^[ \t\r\n]+$/, v = new n({
                            validate: k,
                            allow_script_urls: r.allow_script_urls,
                            allow_conditional_comments: r.allow_conditional_comments,
                            self_closing_elements: g(l.getSelfClosingElements()),
                            cdata: function(e) {
                                b.append(u("#cdata", 4)).value = e
                            },
                            text: function(e, t) {
                                var n;
                                B || (e = e.replace(M, " "), b.lastChild && T[b.lastChild.name] && (e = e.replace(R, ""))), 0 !== e.length && (n = u("#text", 3), n.raw = !!t, b.append(n).value = e)
                            },
                            comment: function(e) {
                                b.append(u("#comment", 8)).value = e
                            },
                            pi: function(e, t) {
                                b.append(u(e, 7)).value = t, m(b)
                            },
                            doctype: function(e) {
                                var t;
                                t = b.append(u("#doctype", 10)), t.value = e, m(b)
                            },
                            start: function(e, t, n) {
                                var r, i, o, a, s;
                                if (o = k ? l.getElementRule(e) : {}) {
                                    for (r = u(o.outputName || e, 1), r.attributes = t, r.shortEnded = n, b.append(r), s = H[b.name], s && H[r.name] && !s[r.name] && A.push(r), i = f.length; i--;) a = f[i].name, a in t.map && (_ = p[a], _ ? _.push(r) : p[a] = [r]);
                                    T[e] && m(r), n || (b = r), !B && P[e] && (B = !0)
                                }
                            },
                            end: function(t) {
                                var n, r, i, o, a;
                                if (r = k ? l.getElementRule(t) : {}) {
                                    if (T[t] && !B) {
                                        if (n = b.firstChild, n && 3 === n.type)
                                            if (i = n.value.replace(R, ""), i.length > 0) n.value = i, n = n.next;
                                            else
                                                for (o = n.next, n.remove(), n = o; n && 3 === n.type;) i = n.value, o = n.next, (0 === i.length || L.test(i)) && (n.remove(), n = o), n = o;
                                        if (n = b.lastChild, n && 3 === n.type)
                                            if (i = n.value.replace(D, ""), i.length > 0) n.value = i, n = n.prev;
                                            else
                                                for (o = n.prev, n.remove(), n = o; n && 3 === n.type;) i = n.value, o = n.prev, (0 === i.length || L.test(i)) && (n.remove(), n = o), n = o
                                    }
                                    if (B && P[t] && (B = !1), (r.removeEmpty || r.paddEmpty) && b.isEmpty(O))
                                        if (r.paddEmpty) b.empty().append(new e("#text", "3")).value = "\xa0";
                                        else if (!b.attributes.map.name && !b.attributes.map.id) return a = b.parent, T[b.name] ? b.empty().remove() : b.unwrap(), void(b = a);
                                    b = b.parent
                                }
                            }
                        }, l), y = b = new e(o.context || r.root_name, 11), v.parse(t), k && A.length && (o.context ? o.invalid = !0 : c(A)), I && ("body" == y.name || o.isRootContent) && a(), !o.invalid) {
                        for (S in h) {
                            for (_ = d[S], C = h[S], E = C.length; E--;) C[E].parent || C.splice(E, 1);
                            for (x = 0, w = _.length; w > x; x++) _[x](C, S, o)
                        }
                        for (x = 0, w = f.length; w > x; x++)
                            if (_ = f[x], _.name in p) {
                                for (C = p[_.name], E = C.length; E--;) C[E].parent || C.splice(E, 1);
                                for (E = 0, N = _.callbacks.length; N > E; E++) _.callbacks[E](C, _.name, o)
                            }
                    }
                    return y
                }, r.remove_trailing_brs && u.addNodeFilter("br", function(t) {
                    var n, r = t.length,
                        i, o = s({}, l.getBlockElements()),
                        a = l.getNonEmptyElements(),
                        c, u, d, f, h, p;
                    for (o.body = 1, n = 0; r > n; n++)
                        if (i = t[n], c = i.parent, o[i.parent.name] && i === c.lastChild) {
                            for (d = i.prev; d;) {
                                if (f = d.name, "span" !== f || "bookmark" !== d.attr("data-mce-type")) {
                                    if ("br" !== f) break;
                                    if ("br" === f) {
                                        i = null;
                                        break
                                    }
                                }
                                d = d.prev
                            }
                            i && (i.remove(), c.isEmpty(a) && (h = l.getElementRule(c.name), h && (h.removeEmpty ? c.remove() : h.paddEmpty && (c.empty().append(new e("#text", 3)).value = "\xa0"))))
                        } else {
                            for (u = i; c && c.firstChild === u && c.lastChild === u && (u = c, !o[c.name]);) c = c.parent;
                            u === c && (p = new e("#text", 3), p.value = "\xa0", i.replace(p))
                        }
                }), r.allow_html_in_named_anchor || u.addAttributeFilter("id,name", function(e) {
                    for (var t = e.length, n, r, i, o; t--;)
                        if (o = e[t], "a" === o.name && o.firstChild && !o.attr("href")) {
                            i = o.parent, n = o.lastChild;
                            do r = n.prev, i.insert(n, o), n = r; while (n)
                        }
                }), r.validate && l.getValidClasses() && u.addAttributeFilter("class", function(e) {
                    for (var t = e.length, n, r, i, o, a, s = l.getValidClasses(), c, u; t--;) {
                        for (n = e[t], r = n.attr("class").split(" "), a = "", i = 0; i < r.length; i++) o = r[i], u = !1, c = s["*"], c && c[o] && (u = !0), c = s[n.name], !u && c && c[o] && (u = !0), u && (a && (a += " "), a += o);
                        a.length || (a = null), n.attr("class", a)
                    }
                })
            }
        }), r(L, [C, m], function(e, t) {
            var n = t.makeMap;
            return function(t) {
                var r = [],
                    i, o, a, s, l;
                return t = t || {}, i = t.indent, o = n(t.indent_before || ""), a = n(t.indent_after || ""), s = e.getEncodeFunc(t.entity_encoding || "raw", t.entities), l = "html" == t.element_format, {
                    start: function(e, t, n) {
                        var c, u, d, f;
                        if (i && o[e] && r.length > 0 && (f = r[r.length - 1], f.length > 0 && "\n" !== f && r.push("\n")), r.push("<", e), t)
                            for (c = 0, u = t.length; u > c; c++) d = t[c], r.push(" ", d.name, '="', s(d.value, !0), '"');
                        !n || l ? r[r.length] = ">" : r[r.length] = " />", n && i && a[e] && r.length > 0 && (f = r[r.length - 1], f.length > 0 && "\n" !== f && r.push("\n"))
                    },
                    end: function(e) {
                        var t;
                        r.push("</", e, ">"), i && a[e] && r.length > 0 && (t = r[r.length - 1], t.length > 0 && "\n" !== t && r.push("\n"))
                    },
                    text: function(e, t) {
                        e.length > 0 && (r[r.length] = t ? e : s(e))
                    },
                    cdata: function(e) {
                        r.push("<![CDATA[", e, "]]>")
                    },
                    comment: function(e) {
                        r.push("<!--", e, "-->")
                    },
                    pi: function(e, t) {
                        t ? r.push("<?", e, " ", s(t), "?>") : r.push("<?", e, "?>"), i && r.push("\n")
                    },
                    doctype: function(e) {
                        r.push("<!DOCTYPE", e, ">", i ? "\n" : "")
                    },
                    reset: function() {
                        r.length = 0
                    },
                    getContent: function() {
                        return r.join("").replace(/\n$/, "")
                    }
                }
            }
        }), r(P, [L, B], function(e, t) {
            return function(n, r) {
                var i = this,
                    o = new e(n);
                n = n || {}, n.validate = "validate" in n ? n.validate : !0, i.schema = r = r || new t, i.writer = o, i.serialize = function(e) {
                    function t(e) {
                        var n = i[e.type],
                            s, l, c, u, d, f, h, p, m;
                        if (n) n(e);
                        else {
                            if (s = e.name, l = e.shortEnded, c = e.attributes, a && c && c.length > 1 && (f = [], f.map = {}, m = r.getElementRule(e.name))) {
                                for (h = 0, p = m.attributesOrder.length; p > h; h++) u = m.attributesOrder[h], u in c.map && (d = c.map[u], f.map[u] = d, f.push({
                                    name: u,
                                    value: d
                                }));
                                for (h = 0, p = c.length; p > h; h++) u = c[h].name, u in f.map || (d = c.map[u], f.map[u] = d, f.push({
                                    name: u,
                                    value: d
                                }));
                                c = f
                            }
                            if (o.start(e.name, c, l), !l) {
                                if (e = e.firstChild)
                                    do t(e); while (e = e.next);
                                o.end(s)
                            }
                        }
                    }
                    var i, a;
                    return a = n.validate, i = {
                        3: function(e) {
                            o.text(e.value, e.raw)
                        },
                        8: function(e) {
                            o.comment(e.value)
                        },
                        7: function(e) {
                            o.pi(e.name, e.value)
                        },
                        10: function(e) {
                            o.doctype(e.value)
                        },
                        4: function(e) {
                            o.cdata(e.value)
                        },
                        11: function(e) {
                            if (e = e.firstChild)
                                do t(e); while (e = e.next)
                        }
                    }, o.reset(), 1 != e.type || n.inner ? i[11](e) : t(e), o.getContent()
                }
            }
        }), r(H, [w, M, D, C, P, A, B, h, m, S], function(e, t, n, r, i, o, a, s, l, c) {
            function u(e) {
                function t(e) {
                    return e && "br" === e.name
                }
                var n, r;
                n = e.lastChild, t(n) && (r = n.prev, t(r) && (n.remove(), r.remove()))
            }
            var d = l.each,
                f = l.trim,
                h = e.DOM,
                p = new RegExp(["<span[^>]+data-mce-bogus[^>]+>[\u200b\ufeff]+<\\/span>", '\\s?data-mce-selected="[^"]+"'].join("|"), "gi");
            return function(e, o) {
                function l() {
                    var e = o.getBody().innerHTML,
                        t = /<(\w+) [^>]*data-mce-bogus="all"[^>]*>/g,
                        r, i, a, s, l, u = o.schema;
                    for (e = c.trim(e.replace(p, "")), l = u.getShortEndedElements(); s = t.exec(e);) i = t.lastIndex, a = s[0].length, r = l[s[1]] ? i : n.findEndTag(u, e, i), e = e.substring(0, i - a) + e.substring(r), t.lastIndex = i - a;
                    return f(e)
                }
                var m, g, v;
                return o && (m = o.dom, g = o.schema), m = m || h, g = g || new a(e), e.entity_encoding = e.entity_encoding || "named", e.remove_trailing_brs = "remove_trailing_brs" in e ? e.remove_trailing_brs : !0, v = new t(e, g), v.addAttributeFilter("data-mce-tabindex", function(e, t) {
                    for (var n = e.length, r; n--;) r = e[n], r.attr("tabindex", r.attributes.map["data-mce-tabindex"]), r.attr(t, null)
                }), v.addAttributeFilter("src,href,style", function(t, n) {
                    for (var r = t.length, i, o, a = "data-mce-" + n, s = e.url_converter, l = e.url_converter_scope, c; r--;) i = t[r], o = i.attributes.map[a], o !== c ? (i.attr(n, o.length > 0 ? o : null), i.attr(a, null)) : (o = i.attributes.map[n], "style" === n ? o = m.serializeStyle(m.parseStyle(o), i.name) : s && (o = s.call(l, o, n, i.name)), i.attr(n, o.length > 0 ? o : null))
                }), v.addAttributeFilter("class", function(e) {
                    for (var t = e.length, n, r; t--;) n = e[t], r = n.attr("class"), r && (r = n.attr("class").replace(/(?:^|\s)mce-item-\w+(?!\S)/g, ""), n.attr("class", r.length > 0 ? r : null))
                }), v.addAttributeFilter("data-mce-type", function(e, t, n) {
                    for (var r = e.length, i; r--;) i = e[r], "bookmark" !== i.attributes.map["data-mce-type"] || n.cleanup || i.remove()
                }), v.addNodeFilter("noscript", function(e) {
                    for (var t = e.length, n; t--;) n = e[t].firstChild, n && (n.value = r.decode(n.value))
                }), v.addNodeFilter("script,style", function(e, t) {
                    function n(e) {
                        return e.replace(/(<!--\[CDATA\[|\]\]-->)/g, "\n").replace(/^[\r\n]*|[\r\n]*$/g, "").replace(/^\s*((<!--)?(\s*\/\/)?\s*<!\[CDATA\[|(<!--\s*)?\/\*\s*<!\[CDATA\[\s*\*\/|(\/\/)?\s*<!--|\/\*\s*<!--\s*\*\/)\s*[\r\n]*/gi, "").replace(/\s*(\/\*\s*\]\]>\s*\*\/(-->)?|\s*\/\/\s*\]\]>(-->)?|\/\/\s*(-->)?|\]\]>|\/\*\s*-->\s*\*\/|\s*-->\s*)\s*$/g, "")
                    }
                    for (var r = e.length, i, o, a; r--;) i = e[r], o = i.firstChild ? i.firstChild.value : "", "script" === t ? (a = i.attr("type"), a && i.attr("type", "mce-no/type" == a ? null : a.replace(/^mce\-/, "")), o.length > 0 && (i.firstChild.value = "// <![CDATA[\n" + n(o) + "\n// ]]>")) : o.length > 0 && (i.firstChild.value = "<!--\n" + n(o) + "\n-->")
                }), v.addNodeFilter("#comment", function(e) {
                    for (var t = e.length, n; t--;) n = e[t], 0 === n.value.indexOf("[CDATA[") ? (n.name = "#cdata", n.type = 4, n.value = n.value.replace(/^\[CDATA\[|\]\]$/g, "")) : 0 === n.value.indexOf("mce:protected ") && (n.name = "#text", n.type = 3, n.raw = !0, n.value = unescape(n.value).substr(14))
                }), v.addNodeFilter("xml:namespace,input", function(e, t) {
                    for (var n = e.length, r; n--;) r = e[n], 7 === r.type ? r.remove() : 1 === r.type && ("input" !== t || "type" in r.attributes.map || r.attr("type", "text"))
                }), e.fix_list_elements && v.addNodeFilter("ul,ol", function(e) {
                    for (var t = e.length, n, r; t--;) n = e[t], r = n.parent, ("ul" === r.name || "ol" === r.name) && n.prev && "li" === n.prev.name && n.prev.append(n)
                }), v.addAttributeFilter("data-mce-src,data-mce-href,data-mce-style,data-mce-selected,data-mce-expando,data-mce-type,data-mce-resize", function(e, t) {
                    for (var n = e.length; n--;) e[n].attr(t, null)
                }), {
                    schema: g,
                    addNodeFilter: v.addNodeFilter,
                    addAttributeFilter: v.addAttributeFilter,
                    serialize: function(t, n) {
                        var r = this,
                            o, a, l, h, p, y;
                        return s.ie && m.select("script,style,select,map").length > 0 ? (p = t.innerHTML, t = t.cloneNode(!1), m.setHTML(t, p)) : t = t.cloneNode(!0), o = t.ownerDocument.implementation, o.createHTMLDocument && (a = o.createHTMLDocument(""), d("BODY" == t.nodeName ? t.childNodes : [t], function(e) {
                            a.body.appendChild(a.importNode(e, !0))
                        }), t = "BODY" != t.nodeName ? a.body.firstChild : a.body, l = m.doc, m.doc = a), n = n || {}, n.format = n.format || "html", n.selection && (n.forced_root_block = ""), n.no_events || (n.node = t, r.onPreProcess(n)), y = v.parse(f(n.getInner ? t.innerHTML : m.getOuterHTML(t)), n), u(y), h = new i(e, g), n.content = h.serialize(y), n.cleanup || (n.content = c.trim(n.content), n.content = n.content.replace(/\uFEFF/g, "")), n.no_events || r.onPostProcess(n), l && (m.doc = l), n.node = null, n.content
                    },
                    addRules: function(e) {
                        g.addValidElements(e)
                    },
                    setRules: function(e) {
                        g.setValidElements(e)
                    },
                    onPreProcess: function(e) {
                        o && o.fire("PreProcess", e)
                    },
                    onPostProcess: function(e) {
                        o && o.fire("PostProcess", e)
                    },
                    getTrimmedContent: l
                }
            }
        }), r(O, [], function() {
            function e(e) {
                function t(t, n) {
                    var r, i = 0,
                        o, a, s, l, c, u, d = -1,
                        f;
                    if (r = t.duplicate(), r.collapse(n), f = r.parentElement(), f.ownerDocument === e.dom.doc) {
                        for (;
                            "false" === f.contentEditable;) f = f.parentNode;
                        if (!f.hasChildNodes()) return {
                            node: f,
                            inside: 1
                        };
                        for (s = f.children, o = s.length - 1; o >= i;)
                            if (u = Math.floor((i + o) / 2), l = s[u], r.moveToElementText(l), d = r.compareEndPoints(n ? "StartToStart" : "EndToEnd", t), d > 0) o = u - 1;
                            else {
                                if (!(0 > d)) return {
                                    node: l
                                };
                                i = u + 1
                            }
                        if (0 > d)
                            for (l ? r.collapse(!1) : (r.moveToElementText(f), r.collapse(!0), l = f, a = !0), c = 0; 0 !== r.compareEndPoints(n ? "StartToStart" : "StartToEnd", t) && 0 !== r.move("character", 1) && f == r.parentElement();) c++;
                        else
                            for (r.collapse(!0), c = 0; 0 !== r.compareEndPoints(n ? "StartToStart" : "StartToEnd", t) && 0 !== r.move("character", -1) && f == r.parentElement();) c++;
                        return {
                            node: l,
                            position: d,
                            offset: c,
                            inside: a
                        }
                    }
                }
    
                function n() {
                    function n(e) {
                        var n = t(o, e),
                            r, i, s = 0,
                            l, c, u;
                        if (r = n.node, i = n.offset, n.inside && !r.hasChildNodes()) return void a[e ? "setStart" : "setEnd"](r, 0);
                        if (i === c) return void a[e ? "setStartBefore" : "setEndAfter"](r);
                        if (n.position < 0) {
                            if (l = n.inside ? r.firstChild : r.nextSibling, !l) return void a[e ? "setStartAfter" : "setEndAfter"](r);
                            if (!i) return void(3 == l.nodeType ? a[e ? "setStart" : "setEnd"](l, 0) : a[e ? "setStartBefore" : "setEndBefore"](l));
                            for (; l;) {
                                if (3 == l.nodeType && (u = l.nodeValue, s += u.length, s >= i)) {
                                    r = l, s -= i, s = u.length - s;
                                    break
                                }
                                l = l.nextSibling
                            }
                        } else {
                            if (l = r.previousSibling, !l) return a[e ? "setStartBefore" : "setEndBefore"](r);
                            if (!i) return void(3 == r.nodeType ? a[e ? "setStart" : "setEnd"](l, r.nodeValue.length) : a[e ? "setStartAfter" : "setEndAfter"](l));
                            for (; l;) {
                                if (3 == l.nodeType && (s += l.nodeValue.length, s >= i)) {
                                    r = l, s -= i;
                                    break
                                }
                                l = l.previousSibling
                            }
                        }
                        a[e ? "setStart" : "setEnd"](r, s)
                    }
                    var o = e.getRng(),
                        a = i.createRng(),
                        s, l, c, u, d;
                    if (s = o.item ? o.item(0) : o.parentElement(), s.ownerDocument != i.doc) return a;
                    if (l = e.isCollapsed(), o.item) return a.setStart(s.parentNode, i.nodeIndex(s)), a.setEnd(a.startContainer, a.startOffset + 1), a;
                    try {
                        n(!0), l || n()
                    } catch (f) {
                        if (-2147024809 != f.number) throw f;
                        d = r.getBookmark(2), c = o.duplicate(), c.collapse(!0), s = c.parentElement(), l || (c = o.duplicate(), c.collapse(!1), u = c.parentElement(), u.innerHTML = u.innerHTML), s.innerHTML = s.innerHTML, r.moveToBookmark(d), o = e.getRng(), n(!0), l || n()
                    }
                    return a
                }
                var r = this,
                    i = e.dom,
                    o = !1;
                this.getBookmark = function(n) {
                    function r(e) {
                        var t, n, r, o, a = [];
                        for (t = e.parentNode, n = i.getRoot().parentNode; t != n && 9 !== t.nodeType;) {
                            for (r = t.children, o = r.length; o--;)
                                if (e === r[o]) {
                                    a.push(o);
                                    break
                                }
                            e = t, t = t.parentNode
                        }
                        return a
                    }
    
                    function o(e) {
                        var n;
                        return n = t(a, e), n ? {
                            position: n.position,
                            offset: n.offset,
                            indexes: r(n.node),
                            inside: n.inside
                        } : void 0
                    }
                    var a = e.getRng(),
                        s = {};
                    return 2 === n && (a.item ? s.start = {
                        ctrl: !0,
                        indexes: r(a.item(0))
                    } : (s.start = o(!0), e.isCollapsed() || (s.end = o()))), s
                }, this.moveToBookmark = function(e) {
                    function t(e) {
                        var t, n, r, o;
                        for (t = i.getRoot(), n = e.length - 1; n >= 0; n--) o = t.children, r = e[n], r <= o.length - 1 && (t = o[r]);
                        return t
                    }
    
                    function n(n) {
                        var i = e[n ? "start" : "end"],
                            a, s, l, c;
                        i && (a = i.position > 0, s = o.createTextRange(), s.moveToElementText(t(i.indexes)), c = i.offset, c !== l ? (s.collapse(i.inside || a), s.moveStart("character", a ? -c : c)) : s.collapse(n), r.setEndPoint(n ? "StartToStart" : "EndToStart", s), n && r.collapse(!0))
                    }
                    var r, o = i.doc.body;
                    e.start && (e.start.ctrl ? (r = o.createControlRange(), r.addElement(t(e.start.indexes)), r.select()) : (r = o.createTextRange(), n(!0), n(), r.select()))
                }, this.addRange = function(t) {
                    function n(e) {
                        var t, n, a, d, p;
                        a = i.create("a"), t = e ? s : c, n = e ? l : u, d = r.duplicate(), (t == f || t == f.documentElement) && (t = h, n = 0), 3 == t.nodeType ? (t.parentNode.insertBefore(a, t), d.moveToElementText(a), d.moveStart("character", n), i.remove(a), r.setEndPoint(e ? "StartToStart" : "EndToEnd", d)) : (p = t.childNodes, p.length ? (n >= p.length ? i.insertAfter(a, p[p.length - 1]) : t.insertBefore(a, p[n]), d.moveToElementText(a)) : t.canHaveHTML && (t.innerHTML = "<span>&#xFEFF;</span>", a = t.firstChild, d.moveToElementText(a), d.collapse(o)), r.setEndPoint(e ? "StartToStart" : "EndToEnd", d), i.remove(a))
                    }
                    var r, a, s, l, c, u, d, f = e.dom.doc,
                        h = f.body,
                        p, m;
                    if (s = t.startContainer, l = t.startOffset, c = t.endContainer, u = t.endOffset, r = h.createTextRange(), s == c && 1 == s.nodeType) {
                        if (l == u && !s.hasChildNodes()) {
                            if (s.canHaveHTML) return d = s.previousSibling, d && !d.hasChildNodes() && i.isBlock(d) ? d.innerHTML = "&#xFEFF;" : d = null, s.innerHTML = "<span>&#xFEFF;</span><span>&#xFEFF;</span>", r.moveToElementText(s.lastChild), r.select(), i.doc.selection.clear(), s.innerHTML = "", void(d && (d.innerHTML = ""));
                            l = i.nodeIndex(s), s = s.parentNode
                        }
                        if (l == u - 1) try {
                            if (m = s.childNodes[l], a = h.createControlRange(), a.addElement(m), a.select(), p = e.getRng(), p.item && m === p.item(0)) return
                        } catch (g) {}
                    }
                    n(!0), n(), r.select()
                }, this.getRangeAt = n
            }
            return e
        }), r(I, [h], function(e) {
            return {
                BACKSPACE: 8,
                DELETE: 46,
                DOWN: 40,
                ENTER: 13,
                LEFT: 37,
                RIGHT: 39,
                SPACEBAR: 32,
                TAB: 9,
                UP: 38,
                modifierPressed: function(e) {
                    return e.shiftKey || e.ctrlKey || e.altKey || this.metaKeyPressed(e)
                },
                metaKeyPressed: function(t) {
                    return e.mac ? t.metaKey : t.ctrlKey && !t.altKey
                }
            }
        }), r(F, [I, m, u, h, _], function(e, t, n, r, i) {
            var o = i.isContentEditableFalse;
            return function(i, a) {
                function s(e) {
                    var t = a.settings.object_resizing;
                    return t === !1 || r.iOS ? !1 : ("string" != typeof t && (t = "table,img,div"), "false" === e.getAttribute("data-mce-resize") ? !1 : e == a.getBody() ? !1 : a.dom.is(e, t))
                }
    
                function l(t) {
                    var n, r, i, o, s;
                    n = t.screenX - B, r = t.screenY - D, F = n * R[2] + P, z = r * R[3] + H, F = 5 > F ? 5 : F, z = 5 > z ? 5 : z, i = "IMG" == _.nodeName && a.settings.resize_img_proportional !== !1 ? !e.modifierPressed(t) : e.modifierPressed(t) || "IMG" == _.nodeName && R[2] * R[3] !== 0, i && ($(n) > $(r) ? (z = q(F * O), F = q(z / O)) : (F = q(z / O), z = q(F * O))), E.setStyles(S, {
                        width: F,
                        height: z
                    }), o = R.startPos.x + n, s = R.startPos.y + r, o = o > 0 ? o : 0, s = s > 0 ? s : 0, E.setStyles(k, {
                        left: o,
                        top: s,
                        display: "block"
                    }), k.innerHTML = F + " &times; " + z, R[2] < 0 && S.clientWidth <= F && E.setStyle(S, "left", M + (P - F)), R[3] < 0 && S.clientHeight <= z && E.setStyle(S, "top", L + (H - z)), n = j.scrollWidth - Y, r = j.scrollHeight - X, n + r !== 0 && E.setStyles(k, {
                        left: o - n,
                        top: s - r
                    }), I || (a.fire("ObjectResizeStart", {
                        target: _,
                        width: P,
                        height: H
                    }), I = !0)
                }
    
                function c() {
                    function e(e, t) {
                        t && (_.style[e] || !a.schema.isValid(_.nodeName.toLowerCase(), e) ? E.setStyle(_, e, t) : E.setAttrib(_, e, t))
                    }
                    I = !1, e("width", F), e("height", z), E.unbind(W, "mousemove", l), E.unbind(W, "mouseup", c), V != W && (E.unbind(V, "mousemove", l), E.unbind(V, "mouseup", c)), E.remove(S), E.remove(k), U && "TABLE" != _.nodeName || u(_), a.fire("ObjectResized", {
                        target: _,
                        width: F,
                        height: z
                    }), E.setAttrib(_, "style", E.getAttrib(_, "style")), a.nodeChanged()
                }
    
                function u(e, t, n) {
                    var i, o, u, f, h;
                    d(), b(), i = E.getPos(e, j), M = i.x, L = i.y, h = e.getBoundingClientRect(), o = h.width || h.right - h.left, u = h.height || h.bottom - h.top, _ != e && (y(), _ = e, F = z = 0), f = a.fire("ObjectSelected", {
                        target: e
                    }), s(e) && !f.isDefaultPrevented() ? N(T, function(e, i) {
                        function a(t) {
                            B = t.screenX, D = t.screenY, P = _.clientWidth, H = _.clientHeight, O = H / P, R = e, e.startPos = {
                                x: o * e[0] + M,
                                y: u * e[1] + L
                            }, Y = j.scrollWidth, X = j.scrollHeight, S = _.cloneNode(!0), E.addClass(S, "mce-clonedresizable"), E.setAttrib(S, "data-mce-bogus", "all"), S.contentEditable = !1, S.unSelectabe = !0, E.setStyles(S, {
                                left: M,
                                top: L,
                                margin: 0
                            }), S.removeAttribute("data-mce-selected"), j.appendChild(S), E.bind(W, "mousemove", l), E.bind(W, "mouseup", c), V != W && (E.bind(V, "mousemove", l), E.bind(V, "mouseup", c)), k = E.add(j, "div", {
                                "class": "mce-resize-helper",
                                "data-mce-bogus": "all"
                            }, P + " &times; " + H)
                        }
                        var s;
                        return t ? void(i == t && a(n)) : (s = E.get("mceResizeHandle" + i), s && E.remove(s), s = E.add(j, "div", {
                            id: "mceResizeHandle" + i,
                            "data-mce-bogus": "all",
                            "class": "mce-resizehandle",
                            unselectable: !0,
                            style: "cursor:" + i + "-resize; margin:0; padding:0"
                        }), r.ie && (s.contentEditable = !1), E.bind(s, "mousedown", function(e) {
                            e.stopImmediatePropagation(), e.preventDefault(), a(e)
                        }), e.elm = s, void E.setStyles(s, {
                            left: o * e[0] + M - s.offsetWidth / 2,
                            top: u * e[1] + L - s.offsetHeight / 2
                        }))
                    }) : d(), _.setAttribute("data-mce-selected", "1")
                }
    
                function d() {
                    var e, t;
                    b(), _ && _.removeAttribute("data-mce-selected");
                    for (e in T) t = E.get("mceResizeHandle" + e), t && (E.unbind(t), E.remove(t))
                }
    
                function f(e) {
                    function t(e, t) {
                        if (e)
                            do
                                if (e === t) return !0; while (e = e.parentNode)
                    }
                    var n, r;
                    if (!I && !a.removed) return N(E.select("img[data-mce-selected],hr[data-mce-selected]"), function(e) {
                        e.removeAttribute("data-mce-selected")
                    }), r = "mousedown" == e.type ? e.target : i.getNode(), r = E.$(r).closest(U ? "table" : "table,img,hr")[0], t(r, j) && (C(), n = i.getStart(!0), t(n, r) && t(i.getEnd(!0), r) && (!U || r != n && "IMG" !== n.nodeName)) ? void u(r) : void d()
                }
    
                function h(e, t, n) {
                    e && e.attachEvent && e.attachEvent("on" + t, n)
                }
    
                function p(e, t, n) {
                    e && e.detachEvent && e.detachEvent("on" + t, n)
                }
    
                function m(e) {
                    var t = e.srcElement,
                        n, r, i, o, s, l, c;
                    n = t.getBoundingClientRect(), l = A.clientX - n.left, c = A.clientY - n.top;
                    for (r in T)
                        if (i = T[r], o = t.offsetWidth * i[0], s = t.offsetHeight * i[1], $(o - l) < 8 && $(s - c) < 8) {
                            R = i;
                            break
                        }
                    I = !0, a.fire("ObjectResizeStart", {
                        target: _,
                        width: _.clientWidth,
                        height: _.clientHeight
                    }), a.getDoc().selection.empty(), u(t, r, A)
                }
    
                function g(e) {
                    e.preventDefault ? e.preventDefault() : e.returnValue = !1
                }
    
                function v(e) {
                    var t = e.srcElement;
                    if (o(t)) return void g(e);
                    if (t != _) {
                        if (a.fire("ObjectSelected", {
                                target: t
                            }), y(), 0 === t.id.indexOf("mceResizeHandle")) return void(e.returnValue = !1);
                        ("IMG" == t.nodeName || "TABLE" == t.nodeName) && (d(), _ = t, h(t, "resizestart", m))
                    }
                }
    
                function y() {
                    p(_, "resizestart", m)
                }
    
                function b() {
                    for (var e in T) {
                        var t = T[e];
                        t.elm && (E.unbind(t.elm), delete t.elm)
                    }
                }
    
                function C() {
                    try {
                        a.getDoc().execCommand("enableObjectResizing", !1, !1)
                    } catch (e) {}
                }
    
                function x(e) {
                    var t;
                    if (U) {
                        t = W.body.createControlRange();
                        try {
                            return t.addElement(e), t.select(), !0
                        } catch (n) {}
                    }
                }
    
                function w() {
                    _ = S = null, U && (y(), p(j, "controlselect", v))
                }
                var E = a.dom,
                    N = t.each,
                    _, S, k, T, R, A, B, D, M, L, P, H, O, I, F, z, W = a.getDoc(),
                    V = document,
                    U = r.ie && r.ie < 11,
                    $ = Math.abs,
                    q = Math.round,
                    j = a.getBody(),
                    Y, X;
                T = {
                    nw: [0, 0, -1, -1],
                    ne: [1, 0, 1, -1],
                    se: [1, 1, 1, 1],
                    sw: [0, 1, -1, 1]
                };
                var K = ".mce-content-body";
                return a.contentStyles.push(K + " div.mce-resizehandle {position: absolute;border: 1px solid black;background: #FFF;width: 7px;height: 7px;z-index: 10000}" + K + " .mce-resizehandle:hover {background: #000}" + K + " *[data-mce-selected] {outline: 1px solid black;resize: none}" + K + " .mce-clonedresizable {position: absolute;" + (r.gecko ? "" : "outline: 1px dashed black;") + "opacity: .5;filter: alpha(opacity=50);z-index: 10000}" + K + " .mce-resize-helper {background: #555;background: rgba(0,0,0,0.75);border-radius: 3px;border: 1px;color: white;display: none;font-family: sans-serif;font-size: 12px;white-space: nowrap;line-height: 14px;margin: 5px 10px;padding: 5px;position: absolute;z-index: 10001}"), a.on("init", function() {
                    U ? (a.on("ObjectResized", function(e) {
                        "TABLE" != e.target.nodeName && (d(), x(e.target))
                    }), h(j, "controlselect", v), a.on("mousedown", function(e) {
                        A = e
                    })) : (C(), r.ie >= 11 && (a.on("mousedown click", function(e) {
                        var t = e.target.nodeName;
                        !I && /^(TABLE|IMG|HR)$/.test(t) && (a.selection.select(e.target, "TABLE" == t), "mousedown" == e.type && a.nodeChanged())
                    }), a.dom.bind(j, "mscontrolselect", function(e) {
                        function t(e) {
                            n.setEditorTimeout(a, function() {
                                a.selection.select(e)
                            })
                        }
                        return o(e.target) ? (e.preventDefault(), void t(e.target)) : void(/^(TABLE|IMG|HR)$/.test(e.target.nodeName) && (e.preventDefault(), "IMG" == e.target.tagName && t(e.target)))
                    })));
                    var e = n.throttle(f);
                    a.on("nodechange ResizeEditor ResizeWindow drop", e), a.on("keydown keyup", function(t) {
                        _ && "TABLE" == _.nodeName && e(t)
                    }), a.on("hide blur", d)
                }), a.on("remove", b), {
                    isResizable: s,
                    showResizeRect: u,
                    hideResizeRect: d,
                    updateResizeRect: f,
                    controlSelect: x,
                    destroy: w
                }
            }
        }), r(z, [], function() {
            function e(e) {
                return function() {
                    return e
                }
            }
    
            function t(e) {
                return function(t) {
                    return !e(t)
                }
            }
    
            function n(e, t) {
                return function(n) {
                    return e(t(n))
                }
            }
    
            function r() {
                var e = a.call(arguments);
                return function(t) {
                    for (var n = 0; n < e.length; n++)
                        if (e[n](t)) return !0;
                    return !1
                }
            }
    
            function i() {
                var e = a.call(arguments);
                return function(t) {
                    for (var n = 0; n < e.length; n++)
                        if (!e[n](t)) return !1;
                    return !0
                }
            }
    
            function o(e) {
                var t = a.call(arguments);
                return t.length - 1 >= e.length ? e.apply(this, t.slice(1)) : function() {
                    var e = t.concat([].slice.call(arguments));
                    return o.apply(this, e)
                }
            }
            var a = [].slice;
            return {
                constant: e,
                negate: t,
                and: i,
                or: r,
                curry: o,
                compose: n
            }
        }), r(W, [_, p, k], function(e, t, n) {
            function r(e) {
                return m(e) ? !1 : d(e) ? f(e.parentNode) ? !1 : !0 : h(e) || u(e) || p(e) || c(e)
            }
    
            function i(e, t) {
                for (e = e.parentNode; e && e != t; e = e.parentNode) {
                    if (c(e)) return !1;
                    if (l(e)) return !0
                }
                return !0
            }
    
            function o(e) {
                return c(e) ? t.reduce(e.getElementsByTagName("*"), function(e, t) {
                    return e || l(t)
                }, !1) !== !0 : !1
            }
    
            function a(e) {
                return h(e) || o(e)
            }
    
            function s(e, t) {
                return r(e) && i(e, t)
            }
            var l = e.isContentEditableTrue,
                c = e.isContentEditableFalse,
                u = e.isBr,
                d = e.isText,
                f = e.matchNodeNames("script style textarea"),
                h = e.matchNodeNames("img input textarea hr iframe video audio object"),
                p = e.matchNodeNames("table"),
                m = n.isCaretContainer;
            return {
                isCaretCandidate: r,
                isInEditable: i,
                isAtomic: a,
                isEditableCaretCandidate: s
            }
        }), r(V, [], function() {
            function e(e) {
                return e ? {
                    left: c(e.left),
                    top: c(e.top),
                    bottom: c(e.bottom),
                    right: c(e.right),
                    width: c(e.width),
                    height: c(e.height)
                } : {
                    left: 0,
                    top: 0,
                    bottom: 0,
                    right: 0,
                    width: 0,
                    height: 0
                }
            }
    
            function t(t, n) {
                return t = e(t), n ? t.right = t.left : (t.left = t.left + t.width, t.right = t.left), t.width = 0, t
            }
    
            function n(e, t) {
                return e.left === t.left && e.top === t.top && e.bottom === t.bottom && e.right === t.right
            }
    
            function r(e, t, n) {
                return e >= 0 && e <= Math.min(t.height, n.height) / 2;
            }
    
            function i(e, t) {
                return e.bottom < t.top ? !0 : e.top > t.bottom ? !1 : r(t.top - e.bottom, e, t)
            }
    
            function o(e, t) {
                return e.top > t.bottom ? !0 : e.bottom < t.top ? !1 : r(t.bottom - e.top, e, t)
            }
    
            function a(e, t) {
                return e.left < t.left
            }
    
            function s(e, t) {
                return e.right > t.right
            }
    
            function l(e, t) {
                return i(e, t) ? -1 : o(e, t) ? 1 : a(e, t) ? -1 : s(e, t) ? 1 : 0
            }
            var c = Math.round;
            return {
                clone: e,
                collapse: t,
                isEqual: n,
                isAbove: i,
                isBelow: o,
                isLeft: a,
                isRight: s,
                compare: l
            }
        }), r(U, [], function() {
            function e(e) {
                return "string" == typeof e && e.charCodeAt(0) >= 768 && t.test(e)
            }
            var t = new RegExp("[\u0300-\u036f\u0483-\u0487\u0488-\u0489\u0591-\u05bd\u05bf\u05c1-\u05c2\u05c4-\u05c5\u05c7\u0610-\u061a\u064b-\u065f\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7-\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08e3-\u0902\u093a\u093c\u0941-\u0948\u094d\u0951-\u0957\u0962-\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2-\u09e3\u0a01-\u0a02\u0a3c\u0a41-\u0a42\u0a47-\u0a48\u0a4b-\u0a4d\u0a51\u0a70-\u0a71\u0a75\u0a81-\u0a82\u0abc\u0ac1-\u0ac5\u0ac7-\u0ac8\u0acd\u0ae2-\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62-\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c00\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55-\u0c56\u0c62-\u0c63\u0c81\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc-\u0ccd\u0cd5-\u0cd6\u0ce2-\u0ce3\u0d01\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62-\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb-\u0ebc\u0ec8-\u0ecd\u0f18-\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86-\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039-\u103a\u103d-\u103e\u1058-\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085-\u1086\u108d\u109d\u135d-\u135f\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17b4-\u17b5\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927-\u1928\u1932\u1939-\u193b\u1a17-\u1a18\u1a1b\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1ab0-\u1abd\u1abe\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80-\u1b81\u1ba2-\u1ba5\u1ba8-\u1ba9\u1bab-\u1bad\u1be6\u1be8-\u1be9\u1bed\u1bef-\u1bf1\u1c2c-\u1c33\u1c36-\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1cf4\u1cf8-\u1cf9\u1dc0-\u1df5\u1dfc-\u1dff\u200c-\u200d\u20d0-\u20dc\u20dd-\u20e0\u20e1\u20e2-\u20e4\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302d\u302e-\u302f\u3099-\u309a\ua66f\ua670-\ua672\ua674-\ua67d\ua69e-\ua69f\ua6f0-\ua6f1\ua802\ua806\ua80b\ua825-\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\ua9e5\uaa29-\uaa2e\uaa31-\uaa32\uaa35-\uaa36\uaa43\uaa4c\uaa7c\uaab0\uaab2-\uaab4\uaab7-\uaab8\uaabe-\uaabf\uaac1\uaaec-\uaaed\uaaf6\uabe5\uabe8\uabed\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\uff9e-\uff9f]");
            return {
                isExtendingChar: e
            }
        }), r($, [z, _, w, T, W, V, U], function(e, t, n, r, i, o, a) {
            function s(e) {
                return e && /[\r\n\t ]/.test(e)
            }
    
            function l(e) {
                var t = e.startContainer,
                    n = e.startOffset,
                    r;
                return s(e.toString()) && g(t.parentNode) && (r = t.data, s(r[n - 1]) || s(r[n + 1])) ? !0 : !1
            }
    
            function c(e) {
                function t(e) {
                    var t = e.ownerDocument,
                        n = t.createRange(),
                        r = t.createTextNode("\xa0"),
                        i = e.parentNode,
                        a;
                    return i.insertBefore(r, e), n.setStart(r, 0), n.setEnd(r, 1), a = o.clone(n.getBoundingClientRect()), i.removeChild(r), a
                }
    
                function n(e) {
                    var n, r;
                    return r = e.getClientRects(), n = r.length > 0 ? o.clone(r[0]) : o.clone(e.getBoundingClientRect()), y(e) && 0 === n.left ? t(e) : n
                }
    
                function r(e, t) {
                    return e = o.collapse(e, t), e.width = 1, e.right = e.left + 1, e
                }
    
                function i(e) {
                    0 !== e.height && (c.length > 0 && o.isEqual(e, c[c.length - 1]) || c.push(e))
                }
    
                function s(e, t) {
                    var o = e.ownerDocument.createRange();
                    return t < e.data.length && a.isExtendingChar(e.data[t]) ? c : (t > 0 && (o.setStart(e, t - 1), o.setEnd(e, t), l(o) || i(r(n(o), !1))), void(t < e.data.length && (o.setStart(e, t), o.setEnd(e, t + 1), l(o) || i(r(n(o), !0)))))
                }
                var c = [],
                    u, f;
                if (v(e.container())) return s(e.container(), e.offset()), c;
                if (d(e.container()))
                    if (e.isAtEnd()) f = C(e.container(), e.offset()), v(f) && s(f, f.data.length), m(f) && !y(f) && i(r(n(f), !1));
                    else {
                        if (f = C(e.container(), e.offset()), v(f) && s(f, 0), m(f) && e.isAtEnd()) return i(r(n(f), !1)), c;
                        u = C(e.container(), e.offset() - 1), m(u) && !y(u) && (h(u) || h(f) || !m(f)) && i(r(n(u), !1)), m(f) && i(r(n(f), !0))
                    }
                return c
            }
    
            function u(t, n, r) {
                function i() {
                    return v(t) ? 0 === n : 0 === n
                }
    
                function o() {
                    return v(t) ? n >= t.data.length : n >= t.childNodes.length
                }
    
                function a() {
                    var e;
                    return e = t.ownerDocument.createRange(), e.setStart(t, n), e.setEnd(t, n), e
                }
    
                function s() {
                    return r || (r = c(new u(t, n))), r
                }
    
                function l() {
                    return s().length > 0
                }
    
                function d(e) {
                    return e && t === e.container() && n === e.offset()
                }
    
                function f(e) {
                    return C(t, e ? n - 1 : n)
                }
                return {
                    container: e.constant(t),
                    offset: e.constant(n),
                    toRange: a,
                    getClientRects: s,
                    isVisible: l,
                    isAtStart: i,
                    isAtEnd: o,
                    isEqual: d,
                    getNode: f
                }
            }
            var d = t.isElement,
                f = i.isCaretCandidate,
                h = t.matchStyleValues("display", "block table"),
                p = t.matchStyleValues("float", "left right"),
                m = e.and(d, f, e.negate(p)),
                g = e.negate(t.matchStyleValues("white-space", "pre pre-line pre-wrap")),
                v = t.isText,
                y = t.isBr,
                b = n.nodeIndex,
                C = r.getNode;
            return u.fromRangeStart = function(e) {
                return new u(e.startContainer, e.startOffset)
            }, u.fromRangeEnd = function(e) {
                return new u(e.endContainer, e.endOffset)
            }, u.after = function(e) {
                return new u(e.parentNode, b(e) + 1)
            }, u.before = function(e) {
                return new u(e.parentNode, b(e))
            }, u
        }), r(q, [_, w, z, p, $], function(e, t, n, r, i) {
            function o(e) {
                var t = e.parentNode;
                return v(t) ? o(t) : t
            }
    
            function a(e) {
                return e ? r.reduce(e.childNodes, function(e, t) {
                    return v(t) && "BR" != t.nodeName ? e = e.concat(a(t)) : e.push(t), e
                }, []) : []
            }
    
            function s(e, t) {
                for (;
                    (e = e.previousSibling) && g(e);) t += e.data.length;
                return t
            }
    
            function l(e) {
                return function(t) {
                    return e === t
                }
            }
    
            function c(t) {
                var n, i, s;
                return n = a(o(t)), i = r.findIndex(n, l(t), t), n = n.slice(0, i + 1), s = r.reduce(n, function(e, t, r) {
                    return g(t) && g(n[r - 1]) && e++, e
                }, 0), n = r.filter(n, e.matchNodeNames(t.nodeName)), i = r.findIndex(n, l(t), t), i - s
            }
    
            function u(e) {
                var t;
                return t = g(e) ? "text()" : e.nodeName.toLowerCase(), t + "[" + c(e) + "]"
            }
    
            function d(e, t, n) {
                var r = [];
                for (t = t.parentNode; t != e && (!n || !n(t)); t = t.parentNode) r.push(t);
                return r
            }
    
            function f(t, i) {
                var o, a, l = [],
                    c, f, h;
                return o = i.container(), a = i.offset(), g(o) ? c = s(o, a) : (f = o.childNodes, a >= f.length ? (c = "after", a = f.length - 1) : c = "before", o = f[a]), l.push(u(o)), h = d(t, o), h = r.filter(h, n.negate(e.isBogus)), l = l.concat(r.map(h, function(e) {
                    return u(e)
                })), l.reverse().join("/") + "," + c
            }
    
            function h(t, n, i) {
                var o = a(t);
                return o = r.filter(o, function(e, t) {
                    return !g(e) || !g(o[t - 1])
                }), o = r.filter(o, e.matchNodeNames(n)), o[i]
            }
    
            function p(e, t) {
                for (var n = e, r = 0, o; g(n);) {
                    if (o = n.data.length, t >= r && r + o >= t) {
                        e = n, t -= r;
                        break
                    }
                    if (!g(n.nextSibling)) {
                        e = n, t = o;
                        break
                    }
                    r += o, n = n.nextSibling
                }
                return t > e.data.length && (t = e.data.length), new i(e, t)
            }
    
            function m(e, t) {
                var n, o, a;
                return t ? (n = t.split(","), t = n[0].split("/"), a = n.length > 1 ? n[1] : "before", o = r.reduce(t, function(e, t) {
                    return (t = /([\w\-\(\)]+)\[([0-9]+)\]/.exec(t)) ? ("text()" === t[1] && (t[1] = "#text"), h(e, t[1], parseInt(t[2], 10))) : null
                }, e), o ? g(o) ? p(o, parseInt(a, 10)) : (a = "after" === a ? y(o) + 1 : y(o), new i(o.parentNode, a)) : null) : null
            }
            var g = e.isText,
                v = e.isBogus,
                y = t.nodeIndex;
            return {
                create: f,
                resolve: m
            }
        }), r(j, [h, m, k, q, $, _], function(e, t, n, r, i, o) {
            function a(a) {
                var l = a.dom;
                this.getBookmark = function(e, c) {
                    function u(e, n) {
                        var r = 0;
                        return t.each(l.select(e), function(e) {
                            return "all" !== e.getAttribute("data-mce-bogus") ? e == n ? !1 : void r++ : void 0
                        }), r
                    }
    
                    function d(e) {
                        function t(t) {
                            var n, r, i, o = t ? "start" : "end";
                            n = e[o + "Container"], r = e[o + "Offset"], 1 == n.nodeType && "TR" == n.nodeName && (i = n.childNodes, n = i[Math.min(t ? r : r - 1, i.length - 1)], n && (r = t ? 0 : n.childNodes.length, e["set" + (t ? "Start" : "End")](n, r)))
                        }
                        return t(!0), t(), e
                    }
    
                    function f(e) {
                        function t(e, t) {
                            var r = e[t ? "startContainer" : "endContainer"],
                                i = e[t ? "startOffset" : "endOffset"],
                                o = [],
                                a, s, u = 0;
                            if (3 == r.nodeType) {
                                if (c)
                                    for (a = r.previousSibling; a && 3 == a.nodeType; a = a.previousSibling) i += a.nodeValue.length;
                                o.push(i)
                            } else s = r.childNodes, i >= s.length && s.length && (u = 1, i = Math.max(0, s.length - 1)), o.push(l.nodeIndex(s[i], c) + u);
                            for (; r && r != n; r = r.parentNode) o.push(l.nodeIndex(r, c));
                            return o
                        }
                        var n = l.getRoot(),
                            r = {};
                        return r.start = t(e, !0), a.isCollapsed() || (r.end = t(e)), r
                    }
    
                    function h(e) {
                        function t(e) {
                            var t;
                            if (n.isCaretContainer(e)) {
                                if (o.isText(e) && n.isCaretContainerBlock(e) && (e = e.parentNode), t = e.previousSibling, s(t)) return t;
                                if (t = e.nextSibling, s(t)) return t
                            }
                        }
                        return t(e.startContainer) || t(e.endContainer)
                    }
                    var p, m, g, v, y, b, C = "&#xFEFF;",
                        x;
                    if (2 == e) return b = a.getNode(), y = b ? b.nodeName : null, p = a.getRng(), s(b) || "IMG" == y ? {
                        name: y,
                        index: u(y, b)
                    } : a.tridentSel ? a.tridentSel.getBookmark(e) : (b = h(p), b ? (y = b.tagName, {
                        name: y,
                        index: u(y, b)
                    }) : f(p));
                    if (3 == e) return p = a.getRng(), {
                        start: r.create(l.getRoot(), i.fromRangeStart(p)),
                        end: r.create(l.getRoot(), i.fromRangeEnd(p))
                    };
                    if (e) return {
                        rng: a.getRng()
                    };
                    if (p = a.getRng(), g = l.uniqueId(), v = a.isCollapsed(), x = "overflow:hidden;line-height:0px", p.duplicate || p.item) {
                        if (p.item) return b = p.item(0), y = b.nodeName, {
                            name: y,
                            index: u(y, b)
                        };
                        m = p.duplicate();
                        try {
                            p.collapse(), p.pasteHTML('<span data-mce-type="bookmark" id="' + g + '_start" style="' + x + '">' + C + "</span>"), v || (m.collapse(!1), p.moveToElementText(m.parentElement()), 0 === p.compareEndPoints("StartToEnd", m) && m.move("character", -1), m.pasteHTML('<span data-mce-type="bookmark" id="' + g + '_end" style="' + x + '">' + C + "</span>"))
                        } catch (w) {
                            return null
                        }
                    } else {
                        if (b = a.getNode(), y = b.nodeName, "IMG" == y) return {
                            name: y,
                            index: u(y, b)
                        };
                        m = d(p.cloneRange()), v || (m.collapse(!1), m.insertNode(l.create("span", {
                            "data-mce-type": "bookmark",
                            id: g + "_end",
                            style: x
                        }, C))), p = d(p), p.collapse(!0), p.insertNode(l.create("span", {
                            "data-mce-type": "bookmark",
                            id: g + "_start",
                            style: x
                        }, C))
                    }
                    return a.moveToBookmark({
                        id: g,
                        keep: 1
                    }), {
                        id: g
                    }
                }, this.moveToBookmark = function(n) {
                    function i(e) {
                        var t = n[e ? "start" : "end"],
                            r, i, o, a;
                        if (t) {
                            for (o = t[0], i = d, r = t.length - 1; r >= 1; r--) {
                                if (a = i.childNodes, t[r] > a.length - 1) return;
                                i = a[t[r]]
                            }
                            3 === i.nodeType && (o = Math.min(t[0], i.nodeValue.length)), 1 === i.nodeType && (o = Math.min(t[0], i.childNodes.length)), e ? u.setStart(i, o) : u.setEnd(i, o)
                        }
                        return !0
                    }
    
                    function o(r) {
                        var i = l.get(n.id + "_" + r),
                            o, a, s, c, u = n.keep;
                        if (i && (o = i.parentNode, "start" == r ? (u ? (o = i.firstChild, a = 1) : a = l.nodeIndex(i), f = h = o, p = m = a) : (u ? (o = i.firstChild, a = 1) : a = l.nodeIndex(i), h = o, m = a), !u)) {
                            for (c = i.previousSibling, s = i.nextSibling, t.each(t.grep(i.childNodes), function(e) {
                                    3 == e.nodeType && (e.nodeValue = e.nodeValue.replace(/\uFEFF/g, ""))
                                }); i = l.get(n.id + "_" + r);) l.remove(i, 1);
                            c && s && c.nodeType == s.nodeType && 3 == c.nodeType && !e.opera && (a = c.nodeValue.length, c.appendData(s.nodeValue), l.remove(s), "start" == r ? (f = h = c, p = m = a) : (h = c, m = a))
                        }
                    }
    
                    function s(t) {
                        return !l.isBlock(t) || t.innerHTML || e.ie || (t.innerHTML = '<br data-mce-bogus="1" />'), t
                    }
    
                    function c() {
                        var e, t;
                        return e = l.createRng(), t = r.resolve(l.getRoot(), n.start), e.setStart(t.container(), t.offset()), t = r.resolve(l.getRoot(), n.end), e.setEnd(t.container(), t.offset()), e
                    }
                    var u, d, f, h, p, m;
                    if (n)
                        if (t.isArray(n.start)) {
                            if (u = l.createRng(), d = l.getRoot(), a.tridentSel) return a.tridentSel.moveToBookmark(n);
                            i(!0) && i() && a.setRng(u)
                        } else "string" == typeof n.start ? a.setRng(c(n)) : n.id ? (o("start"), o("end"), f && (u = l.createRng(), u.setStart(s(f), p), u.setEnd(s(h), m), a.setRng(u))) : n.name ? a.select(l.select(n.name)[n.index]) : n.rng && a.setRng(n.rng)
                }
            }
            var s = o.isContentEditableFalse;
            return a.isBookmarkNode = function(e) {
                return e && "SPAN" === e.tagName && "bookmark" === e.getAttribute("data-mce-type")
            }, a
        }), r(Y, [y, O, F, T, j, _, h, m], function(e, n, r, i, o, a, s, l) {
            function c(e, t, i, a) {
                var s = this;
                s.dom = e, s.win = t, s.serializer = i, s.editor = a, s.bookmarkManager = new o(s), s.controlSelection = new r(s, a), s.win.getSelection || (s.tridentSel = new n(s))
            }
            var u = l.each,
                d = l.trim,
                f = s.ie;
            return c.prototype = {
                setCursorLocation: function(e, t) {
                    var n = this,
                        r = n.dom.createRng();
                    e ? (r.setStart(e, t), r.setEnd(e, t), n.setRng(r), n.collapse(!1)) : (n._moveEndPoint(r, n.editor.getBody(), !0), n.setRng(r))
                },
                getContent: function(e) {
                    var n = this,
                        r = n.getRng(),
                        i = n.dom.create("body"),
                        o = n.getSel(),
                        a, s, l;
                    return e = e || {}, a = s = "", e.get = !0, e.format = e.format || "html", e.selection = !0, n.editor.fire("BeforeGetContent", e), "text" == e.format ? n.isCollapsed() ? "" : r.text || (o.toString ? o.toString() : "") : (r.cloneContents ? (l = r.cloneContents(), l && i.appendChild(l)) : r.item !== t || r.htmlText !== t ? (i.innerHTML = "<br>" + (r.item ? r.item(0).outerHTML : r.htmlText), i.removeChild(i.firstChild)) : i.innerHTML = r.toString(), /^\s/.test(i.innerHTML) && (a = " "), /\s+$/.test(i.innerHTML) && (s = " "), e.getInner = !0, e.content = n.isCollapsed() ? "" : a + n.serializer.serialize(i, e) + s, n.editor.fire("GetContent", e), e.content)
                },
                setContent: function(e, t) {
                    var n = this,
                        r = n.getRng(),
                        i, o = n.win.document,
                        a, s;
                    if (t = t || {
                            format: "html"
                        }, t.set = !0, t.selection = !0, t.content = e, t.no_events || n.editor.fire("BeforeSetContent", t), e = t.content, r.insertNode) {
                        e += '<span id="__caret">_</span>', r.startContainer == o && r.endContainer == o ? o.body.innerHTML = e : (r.deleteContents(), 0 === o.body.childNodes.length ? o.body.innerHTML = e : r.createContextualFragment ? r.insertNode(r.createContextualFragment(e)) : (a = o.createDocumentFragment(), s = o.createElement("div"), a.appendChild(s), s.outerHTML = e, r.insertNode(a))), i = n.dom.get("__caret"), r = o.createRange(), r.setStartBefore(i), r.setEndBefore(i), n.setRng(r), n.dom.remove("__caret");
                        try {
                            n.setRng(r)
                        } catch (l) {}
                    } else r.item && (o.execCommand("Delete", !1, null), r = n.getRng()), /^\s+/.test(e) ? (r.pasteHTML('<span id="__mce_tmp">_</span>' + e), n.dom.remove("__mce_tmp")) : r.pasteHTML(e);
                    t.no_events || n.editor.fire("SetContent", t)
                },
                getStart: function(e) {
                    var t = this,
                        n = t.getRng(),
                        r, i, o, a;
                    if (n.duplicate || n.item) {
                        if (n.item) return n.item(0);
                        for (o = n.duplicate(), o.collapse(1), r = o.parentElement(), r.ownerDocument !== t.dom.doc && (r = t.dom.getRoot()), i = a = n.parentElement(); a = a.parentNode;)
                            if (a == r) {
                                r = i;
                                break
                            }
                        return r
                    }
                    return r = n.startContainer, 1 == r.nodeType && r.hasChildNodes() && (e && n.collapsed || (r = r.childNodes[Math.min(r.childNodes.length - 1, n.startOffset)])), r && 3 == r.nodeType ? r.parentNode : r
                },
                getEnd: function(e) {
                    var t = this,
                        n = t.getRng(),
                        r, i;
                    return n.duplicate || n.item ? n.item ? n.item(0) : (n = n.duplicate(), n.collapse(0), r = n.parentElement(), r.ownerDocument !== t.dom.doc && (r = t.dom.getRoot()), r && "BODY" == r.nodeName ? r.lastChild || r : r) : (r = n.endContainer, i = n.endOffset, 1 == r.nodeType && r.hasChildNodes() && (e && n.collapsed || (r = r.childNodes[i > 0 ? i - 1 : i])), r && 3 == r.nodeType ? r.parentNode : r)
                },
                getBookmark: function(e, t) {
                    return this.bookmarkManager.getBookmark(e, t)
                },
                moveToBookmark: function(e) {
                    return this.bookmarkManager.moveToBookmark(e)
                },
                select: function(e, t) {
                    var n = this,
                        r = n.dom,
                        i = r.createRng(),
                        o;
                    if (n.lastFocusBookmark = null, e) {
                        if (!t && n.controlSelection.controlSelect(e)) return;
                        o = r.nodeIndex(e), i.setStart(e.parentNode, o), i.setEnd(e.parentNode, o + 1), t && (n._moveEndPoint(i, e, !0), n._moveEndPoint(i, e)), n.setRng(i)
                    }
                    return e
                },
                isCollapsed: function() {
                    var e = this,
                        t = e.getRng(),
                        n = e.getSel();
                    return !t || t.item ? !1 : t.compareEndPoints ? 0 === t.compareEndPoints("StartToEnd", t) : !n || t.collapsed
                },
                collapse: function(e) {
                    var t = this,
                        n = t.getRng(),
                        r;
                    n.item && (r = n.item(0), n = t.win.document.body.createTextRange(), n.moveToElementText(r)), n.collapse(!!e), t.setRng(n)
                },
                getSel: function() {
                    var e = this.win;
                    return e.getSelection ? e.getSelection() : e.document.selection
                },
                getRng: function(e) {
                    function t(e, t, n) {
                        try {
                            return t.compareBoundaryPoints(e, n)
                        } catch (r) {
                            return -1
                        }
                    }
                    var n = this,
                        r, i, o, a, s, l;
                    if (!n.win) return null;
                    if (a = n.win.document, !e && n.lastFocusBookmark) {
                        var c = n.lastFocusBookmark;
                        return c.startContainer ? (i = a.createRange(), i.setStart(c.startContainer, c.startOffset), i.setEnd(c.endContainer, c.endOffset)) : i = c, i
                    }
                    if (e && n.tridentSel) return n.tridentSel.getRangeAt(0);
                    try {
                        (r = n.getSel()) && (i = r.rangeCount > 0 ? r.getRangeAt(0) : r.createRange ? r.createRange() : a.createRange())
                    } catch (u) {}
                    if (l = n.editor.fire("GetSelectionRange", {
                            range: i
                        }), l.range !== i) return l.range;
                    if (f && i && i.setStart && a.selection) {
                        try {
                            s = a.selection.createRange()
                        } catch (u) {}
                        s && s.item && (o = s.item(0), i = a.createRange(), i.setStartBefore(o), i.setEndAfter(o))
                    }
                    return i || (i = a.createRange ? a.createRange() : a.body.createTextRange()), i.setStart && 9 === i.startContainer.nodeType && i.collapsed && (o = n.dom.getRoot(), i.setStart(o, 0), i.setEnd(o, 0)), n.selectedRange && n.explicitRange && (0 === t(i.START_TO_START, i, n.selectedRange) && 0 === t(i.END_TO_END, i, n.selectedRange) ? i = n.explicitRange : (n.selectedRange = null, n.explicitRange = null)), i
                },
                setRng: function(e, t) {
                    var n = this,
                        r, i, o;
                    if (e)
                        if (e.select) {
                            n.explicitRange = null;
                            try {
                                e.select()
                            } catch (a) {}
                        } else if (n.tridentSel) {
                        if (e.cloneRange) try {
                            n.tridentSel.addRange(e)
                        } catch (a) {}
                    } else {
                        if (r = n.getSel(), o = n.editor.fire("SetSelectionRange", {
                                range: e
                            }), e = o.range, r) {
                            n.explicitRange = e;
                            try {
                                r.removeAllRanges(), r.addRange(e)
                            } catch (a) {}
                            t === !1 && r.extend && (r.collapse(e.endContainer, e.endOffset), r.extend(e.startContainer, e.startOffset)), n.selectedRange = r.rangeCount > 0 ? r.getRangeAt(0) : null
                        }
                        e.collapsed || e.startContainer != e.endContainer || !r.setBaseAndExtent || s.ie || e.endOffset - e.startOffset < 2 && e.startContainer.hasChildNodes() && (i = e.startContainer.childNodes[e.startOffset], i && "IMG" == i.tagName && n.getSel().setBaseAndExtent(i, 0, i, 1))
                    }
                },
                setNode: function(e) {
                    var t = this;
                    return t.setContent(t.dom.getOuterHTML(e)), e
                },
                getNode: function() {
                    function e(e, t) {
                        for (var n = e; e && 3 === e.nodeType && 0 === e.length;) e = t ? e.nextSibling : e.previousSibling;
                        return e || n
                    }
                    var t = this,
                        n = t.getRng(),
                        r, i = n.startContainer,
                        o = n.endContainer,
                        a = n.startOffset,
                        s = n.endOffset,
                        l = t.dom.getRoot();
                    return n ? n.setStart ? (r = n.commonAncestorContainer, !n.collapsed && (i == o && 2 > s - a && i.hasChildNodes() && (r = i.childNodes[a]), 3 === i.nodeType && 3 === o.nodeType && (i = i.length === a ? e(i.nextSibling, !0) : i.parentNode, o = 0 === s ? e(o.previousSibling, !1) : o.parentNode, i && i === o)) ? i : r && 3 == r.nodeType ? r.parentNode : r) : (r = n.item ? n.item(0) : n.parentElement(), r.ownerDocument !== t.win.document && (r = l), r) : l
                },
                getSelectedBlocks: function(t, n) {
                    var r = this,
                        i = r.dom,
                        o, a, s = [];
                    if (a = i.getRoot(), t = i.getParent(t || r.getStart(), i.isBlock), n = i.getParent(n || r.getEnd(), i.isBlock), t && t != a && s.push(t), t && n && t != n) {
                        o = t;
                        for (var l = new e(t, a);
                            (o = l.next()) && o != n;) i.isBlock(o) && s.push(o)
                    }
                    return n && t != n && n != a && s.push(n), s
                },
                isForward: function() {
                    var e = this.dom,
                        t = this.getSel(),
                        n, r;
                    return t && t.anchorNode && t.focusNode ? (n = e.createRng(), n.setStart(t.anchorNode, t.anchorOffset), n.collapse(!0), r = e.createRng(), r.setStart(t.focusNode, t.focusOffset), r.collapse(!0), n.compareBoundaryPoints(n.START_TO_START, r) <= 0) : !0
                },
                normalize: function() {
                    var e = this,
                        t = e.getRng();
                    return s.range && new i(e.dom).normalize(t) && e.setRng(t, e.isForward()), t
                },
                selectorChanged: function(e, t) {
                    var n = this,
                        r;
                    return n.selectorChangedData || (n.selectorChangedData = {}, r = {}, n.editor.on("NodeChange", function(e) {
                        var t = e.element,
                            i = n.dom,
                            o = i.getParents(t, null, i.getRoot()),
                            a = {};
                        u(n.selectorChangedData, function(e, t) {
                            u(o, function(n) {
                                return i.is(n, t) ? (r[t] || (u(e, function(e) {
                                    e(!0, {
                                        node: n,
                                        selector: t,
                                        parents: o
                                    })
                                }), r[t] = e), a[t] = e, !1) : void 0
                            })
                        }), u(r, function(e, n) {
                            a[n] || (delete r[n], u(e, function(e) {
                                e(!1, {
                                    node: t,
                                    selector: n,
                                    parents: o
                                })
                            }))
                        })
                    })), n.selectorChangedData[e] || (n.selectorChangedData[e] = []), n.selectorChangedData[e].push(t), n
                },
                getScrollContainer: function() {
                    for (var e, t = this.dom.getRoot(); t && "BODY" != t.nodeName;) {
                        if (t.scrollHeight > t.clientHeight) {
                            e = t;
                            break
                        }
                        t = t.parentNode
                    }
                    return e
                },
                scrollIntoView: function(e, t) {
                    function n(e) {
                        for (var t = 0, n = 0, r = e; r && r.nodeType;) t += r.offsetLeft || 0, n += r.offsetTop || 0, r = r.offsetParent;
                        return {
                            x: t,
                            y: n
                        }
                    }
                    var r, i, o = this,
                        s = o.dom,
                        l = s.getRoot(),
                        c, u, d = 0;
                    if (a.isElement(e)) {
                        if (t === !1 && (d = e.offsetHeight), "BODY" != l.nodeName) {
                            var f = o.getScrollContainer();
                            if (f) return r = n(e).y - n(f).y + d, u = f.clientHeight, c = f.scrollTop, void((c > r || r + 25 > c + u) && (f.scrollTop = c > r ? r : r - u + 25))
                        }
                        i = s.getViewPort(o.editor.getWin()), r = s.getPos(e).y + d, c = i.y, u = i.h, (r < i.y || r + 25 > c + u) && o.editor.getWin().scrollTo(0, c > r ? r : r - u + 25)
                    }
                },
                placeCaretAt: function(e, t) {
                    this.setRng(i.getCaretRangeFromPoint(e, t, this.editor.getDoc()))
                },
                _moveEndPoint: function(t, n, r) {
                    var i = n,
                        o = new e(n, i),
                        a = this.dom.schema.getNonEmptyElements();
                    do {
                        if (3 == n.nodeType && 0 !== d(n.nodeValue).length) return void(r ? t.setStart(n, 0) : t.setEnd(n, n.nodeValue.length));
                        if (a[n.nodeName] && !/^(TD|TH)$/.test(n.nodeName)) return void(r ? t.setStartBefore(n) : "BR" == n.nodeName ? t.setEndBefore(n) : t.setEndAfter(n));
                        if (s.ie && s.ie < 11 && this.dom.isBlock(n) && this.dom.isEmpty(n)) return void(r ? t.setStart(n, 0) : t.setEnd(n, 0))
                    } while (n = r ? o.next() : o.prev());
                    "BODY" == i.nodeName && (r ? t.setStart(i, 0) : t.setEnd(i, i.childNodes.length))
                },
                destroy: function() {
                    this.win = null, this.controlSelection.destroy()
                }
            }, c
        }), r(X, [j, m], function(e, t) {
            function n(t) {
                this.compare = function(n, i) {
                    function o(e) {
                        var n = {};
                        return r(t.getAttribs(e), function(r) {
                            var i = r.nodeName.toLowerCase();
                            0 !== i.indexOf("_") && "style" !== i && "data-mce-style" !== i && (n[i] = t.getAttrib(e, i))
                        }), n
                    }
    
                    function a(e, t) {
                        var n, r;
                        for (r in e)
                            if (e.hasOwnProperty(r)) {
                                if (n = t[r], "undefined" == typeof n) return !1;
                                if (e[r] != n) return !1;
                                delete t[r]
                            }
                        for (r in t)
                            if (t.hasOwnProperty(r)) return !1;
                        return !0
                    }
                    return n.nodeName != i.nodeName ? !1 : a(o(n), o(i)) && a(t.parseStyle(t.getAttrib(n, "style")), t.parseStyle(t.getAttrib(i, "style"))) ? !e.isBookmarkNode(n) && !e.isBookmarkNode(i) : !1
                }
            }
            var r = t.each;
            return n
        }), r(K, [m], function(e) {
            function t(e, t) {
                function r(e) {
                    return e.replace(/%(\w+)/g, "")
                }
                var i, o, a = e.dom,
                    s = "",
                    l, c;
                if (c = e.settings.preview_styles, c === !1) return "";
                if (c || (c = "font-family font-size font-weight font-style text-decoration text-transform color background-color border border-radius outline text-shadow"), "string" == typeof t) {
                    if (t = e.formatter.get(t), !t) return;
                    t = t[0]
                }
                return i = t.block || t.inline || "span", o = a.create(i), n(t.styles, function(e, t) {
                    e = r(e), e && a.setStyle(o, t, e)
                }), n(t.attributes, function(e, t) {
                    e = r(e), e && a.setAttrib(o, t, e)
                }), n(t.classes, function(e) {
                    e = r(e), a.hasClass(o, e) || a.addClass(o, e)
                }), e.fire("PreviewFormats"), a.setStyles(o, {
                    position: "absolute",
                    left: -65535
                }), e.getBody().appendChild(o), l = a.getStyle(e.getBody(), "fontSize", !0), l = /px$/.test(l) ? parseInt(l, 10) : 0, n(c.split(" "), function(t) {
                    var n = a.getStyle(o, t, !0);
                    if (!("background-color" == t && /transparent|rgba\s*\([^)]+,\s*0\)/.test(n) && (n = a.getStyle(e.getBody(), t, !0), "#ffffff" == a.toHex(n).toLowerCase()) || "color" == t && "#000000" == a.toHex(n).toLowerCase())) {
                        if ("font-size" == t && /em|%$/.test(n)) {
                            if (0 === l) return;
                            n = parseFloat(n, 10) / (/%$/.test(n) ? 100 : 1), n = n * l + "px"
                        }
                        "border" == t && n && (s += "padding:0 2px;"), s += t + ":" + n + ";"
                    }
                }), e.fire("AfterPreviewFormats"), a.remove(o), s
            }
            var n = e.each;
            return {
                getCssText: t
            }
        }), r(G, [y, T, j, X, m, K], function(e, t, n, r, i, o) {
            return function(a) {
                function s(e) {
                    return e.nodeType && (e = e.nodeName), !!a.schema.getTextBlockElements()[e.toLowerCase()]
                }
    
                function l(e) {
                    return /^(TH|TD)$/.test(e.nodeName)
                }
    
                function c(e) {
                    return e && /^(IMG)$/.test(e.nodeName)
                }
    
                function u(e, t) {
                    return q.getParents(e, t, q.getRoot())
                }
    
                function d(e) {
                    return 1 === e.nodeType && "_mce_caret" === e.id
                }
    
                function f() {
                    m({
                        valigntop: [{
                            selector: "td,th",
                            styles: {
                                verticalAlign: "top"
                            }
                        }],
                        valignmiddle: [{
                            selector: "td,th",
                            styles: {
                                verticalAlign: "middle"
                            }
                        }],
                        valignbottom: [{
                            selector: "td,th",
                            styles: {
                                verticalAlign: "bottom"
                            }
                        }],
                        alignleft: [{
                            selector: "figure.image",
                            collapsed: !1,
                            classes: "align-left",
                            ceFalseOverride: !0
                        }, {
                            selector: "figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li",
                            styles: {
                                textAlign: "left"
                            },
                            defaultBlock: "div"
                        }, {
                            selector: "img,table",
                            collapsed: !1,
                            styles: {
                                "float": "left"
                            }
                        }],
                        aligncenter: [{
                            selector: "figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li",
                            styles: {
                                textAlign: "center"
                            },
                            defaultBlock: "div"
                        }, {
                            selector: "figure.image",
                            collapsed: !1,
                            classes: "align-center",
                            ceFalseOverride: !0
                        }, {
                            selector: "img",
                            collapsed: !1,
                            styles: {
                                display: "block",
                                marginLeft: "auto",
                                marginRight: "auto"
                            }
                        }, {
                            selector: "table",
                            collapsed: !1,
                            styles: {
                                marginLeft: "auto",
                                marginRight: "auto"
                            }
                        }],
                        alignright: [{
                            selector: "figure.image",
                            collapsed: !1,
                            classes: "align-right",
                            ceFalseOverride: !0
                        }, {
                            selector: "figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li",
                            styles: {
                                textAlign: "right"
                            },
                            defaultBlock: "div"
                        }, {
                            selector: "img,table",
                            collapsed: !1,
                            styles: {
                                "float": "right"
                            }
                        }],
                        alignjustify: [{
                            selector: "figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li",
                            styles: {
                                textAlign: "justify"
                            },
                            defaultBlock: "div"
                        }],
                        bold: [{
                            inline: "strong",
                            remove: "all"
                        }, {
                            inline: "span",
                            styles: {
                                fontWeight: "bold"
                            }
                        }, {
                            inline: "b",
                            remove: "all"
                        }],
                        italic: [{
                            inline: "em",
                            remove: "all"
                        }, {
                            inline: "span",
                            styles: {
                                fontStyle: "italic"
                            }
                        }, {
                            inline: "i",
                            remove: "all"
                        }],
                        underline: [{
                            inline: "span",
                            styles: {
                                textDecoration: "underline"
                            },
                            exact: !0
                        }, {
                            inline: "u",
                            remove: "all"
                        }],
                        strikethrough: [{
                            inline: "span",
                            styles: {
                                textDecoration: "line-through"
                            },
                            exact: !0
                        }, {
                            inline: "strike",
                            remove: "all"
                        }],
                        forecolor: {
                            inline: "span",
                            styles: {
                                color: "%value"
                            },
                            links: !0,
                            remove_similar: !0
                        },
                        hilitecolor: {
                            inline: "span",
                            styles: {
                                backgroundColor: "%value"
                            },
                            links: !0,
                            remove_similar: !0
                        },
                        fontname: {
                            inline: "span",
                            styles: {
                                fontFamily: "%value"
                            }
                        },
                        fontsize: {
                            inline: "span",
                            styles: {
                                fontSize: "%value"
                            }
                        },
                        fontsize_class: {
                            inline: "span",
                            attributes: {
                                "class": "%value"
                            }
                        },
                        blockquote: {
                            block: "blockquote",
                            wrapper: 1,
                            remove: "all"
                        },
                        subscript: {
                            inline: "sub"
                        },
                        superscript: {
                            inline: "sup"
                        },
                        code: {
                            inline: "code"
                        },
                        link: {
                            inline: "a",
                            selector: "a",
                            remove: "all",
                            split: !0,
                            deep: !0,
                            onmatch: function() {
                                return !0
                            },
                            onformat: function(e, t, n) {
                                le(n, function(t, n) {
                                    q.setAttrib(e, n, t)
                                })
                            }
                        },
                        removeformat: [{
                            selector: "b,strong,em,i,font,u,strike,sub,sup,dfn,code,samp,kbd,var,cite,mark,q,del,ins",
                            remove: "all",
                            split: !0,
                            expand: !1,
                            block_expand: !0,
                            deep: !0
                        }, {
                            selector: "span",
                            attributes: ["style", "class"],
                            remove: "empty",
                            split: !0,
                            expand: !1,
                            deep: !0
                        }, {
                            selector: "*",
                            attributes: ["style", "class"],
                            split: !1,
                            expand: !1,
                            deep: !0
                        }]
                    }), le("p h1 h2 h3 h4 h5 h6 div address pre div dt dd samp".split(/\s/), function(e) {
                        m(e, {
                            block: e,
                            remove: "all"
                        })
                    }), m(a.settings.formats)
                }
    
                function h() {
                    a.addShortcut("meta+b", "bold_desc", "Bold"), a.addShortcut("meta+i", "italic_desc", "Italic"), a.addShortcut("meta+u", "underline_desc", "Underline");
                    for (var e = 1; 6 >= e; e++) a.addShortcut("access+" + e, "", ["FormatBlock", !1, "h" + e]);
                    a.addShortcut("access+7", "", ["FormatBlock", !1, "p"]), a.addShortcut("access+8", "", ["FormatBlock", !1, "div"]), a.addShortcut("access+9", "", ["FormatBlock", !1, "address"])
                }
    
                function p(e) {
                    return e ? $[e] : $
                }
    
                function m(e, t) {
                    e && ("string" != typeof e ? le(e, function(e, t) {
                        m(t, e)
                    }) : (t = t.length ? t : [t], le(t, function(e) {
                        e.deep === re && (e.deep = !e.selector), e.split === re && (e.split = !e.selector || e.inline), e.remove === re && e.selector && !e.inline && (e.remove = "none"), e.selector && e.inline && (e.mixed = !0, e.block_expand = !0), "string" == typeof e.classes && (e.classes = e.classes.split(/\s+/))
                    }), $[e] = t))
                }
    
                function g(e) {
                    return e && $[e] && delete $[e], $
                }
    
                function v(e) {
                    var t;
                    return a.dom.getParent(e, function(e) {
                        return t = a.dom.getStyle(e, "text-decoration"), t && "none" !== t
                    }), t
                }
    
                function y(e) {
                    var t;
                    1 === e.nodeType && e.parentNode && 1 === e.parentNode.nodeType && (t = v(e.parentNode), a.dom.getStyle(e, "color") && t ? a.dom.setStyle(e, "text-decoration", t) : a.dom.getStyle(e, "text-decoration") === t && a.dom.setStyle(e, "text-decoration", null))
                }
    
                function b(t, n, r) {
                    function i(e, t) {
                        if (t = t || u, e) {
                            if (t.onformat && t.onformat(e, t, n, r), le(t.styles, function(t, r) {
                                    q.setStyle(e, r, D(t, n))
                                }), t.styles) {
                                var i = q.getAttrib(e, "style");
                                i && e.setAttribute("data-mce-style", i)
                            }
                            le(t.attributes, function(t, r) {
                                q.setAttrib(e, r, D(t, n))
                            }), le(t.classes, function(t) {
                                t = D(t, n), q.hasClass(e, t) || q.addClass(e, t)
                            })
                        }
                    }
    
                    function o() {
                        function t(t, n) {
                            var i = new e(n);
                            for (r = i.current(); r; r = i.prev())
                                if (r.childNodes.length > 1 || r == t || "BR" == r.tagName) return r
                        }
                        var n = a.selection.getRng(),
                            i = n.startContainer,
                            o = n.endContainer;
                        if (i != o && 0 === n.endOffset) {
                            var s = t(i, o),
                                l = 3 == s.nodeType ? s.length : s.childNodes.length;
                            n.setEnd(s, l)
                        }
                        return n
                    }
    
                    function l(e, r, o) {
                        var a = [],
                            l, f, h = !0;
                        l = u.inline || u.block, f = q.create(l), i(f), Y.walk(e, function(e) {
                            function r(e) {
                                var g, v, y, b, C;
                                return C = h, g = e.nodeName.toLowerCase(), v = e.parentNode.nodeName.toLowerCase(), 1 === e.nodeType && ie(e) && (C = h, h = "true" === ie(e), b = !0), R(g, "br") ? (p = 0, void(u.block && q.remove(e))) : u.wrapper && w(e, t, n) ? void(p = 0) : h && !b && u.block && !u.wrapper && s(g) && X(v, l) ? (e = q.rename(e, l), i(e), a.push(e), void(p = 0)) : u.selector && (le(c, function(t) {
                                    return "collapsed" in t && t.collapsed !== m ? void 0 : q.is(e, t.selector) && !d(e) ? (i(e, t), y = !0, !1) : void 0
                                }), !u.inline || y) ? void(p = 0) : void(!h || b || !X(l, g) || !X(v, l) || !o && 3 === e.nodeType && 1 === e.nodeValue.length && 65279 === e.nodeValue.charCodeAt(0) || d(e) || u.inline && K(e) ? (p = 0, le(ce(e.childNodes), r), b && (h = C), p = 0) : (p || (p = q.clone(f, ee), e.parentNode.insertBefore(p, e), a.push(p)), p.appendChild(e)))
                            }
                            var p;
                            le(e, r)
                        }), u.links === !0 && le(a, function(e) {
                            function t(e) {
                                "A" === e.nodeName && i(e, u), le(ce(e.childNodes), t)
                            }
                            t(e)
                        }), le(a, function(e) {
                            function r(e) {
                                var t = 0;
                                return le(e.childNodes, function(e) {
                                    M(e) || se(e) || t++
                                }), t
                            }
    
                            function o(e) {
                                var t, n;
                                return le(e.childNodes, function(e) {
                                    return 1 != e.nodeType || se(e) || d(e) ? void 0 : (t = e, ee)
                                }), t && !se(t) && T(t, u) && (n = q.clone(t, ee), i(n), q.replace(n, e, te), q.remove(t, 1)), n || e
                            }
                            var s;
                            if (s = r(e), (a.length > 1 || !K(e)) && 0 === s) return void q.remove(e, 1);
                            if (u.inline || u.wrapper) {
                                if (u.exact || 1 !== s || (e = o(e)), le(c, function(t) {
                                        le(q.select(t.inline, e), function(e) {
                                            se(e) || O(t, n, e, t.exact ? e : null)
                                        })
                                    }), w(e.parentNode, t, n)) return q.remove(e, 1), e = 0, te;
                                u.merge_with_parents && q.getParent(e.parentNode, function(r) {
                                    return w(r, t, n) ? (q.remove(e, 1), e = 0, te) : void 0
                                }), e && u.merge_siblings !== !1 && (e = z(F(e), e), e = z(e, F(e, te)))
                            }
                        })
                    }
                    var c = p(t),
                        u = c[0],
                        f, h, m = !r && j.isCollapsed();
                    if ("false" !== ie(j.getNode())) {
                        if (u)
                            if (r) r.nodeType ? (h = q.createRng(), h.setStartBefore(r), h.setEndAfter(r), l(P(h, c), null, !0)) : l(r, null, !0);
                            else if (m && u.inline && !q.select("td.mce-item-selected,th.mce-item-selected").length) V("apply", t, n);
                        else {
                            var g = a.selection.getNode();
                            G || !c[0].defaultBlock || q.getParent(g, q.isBlock) || b(c[0].defaultBlock), a.selection.setRng(o()), f = j.getBookmark(), l(P(j.getRng(te), c), f), u.styles && (u.styles.color || u.styles.textDecoration) && (ue(g, y, "childNodes"), y(g)), j.moveToBookmark(f), U(j.getRng(te)), a.nodeChanged()
                        }
                    } else {
                        r = j.getNode();
                        for (var v = 0, C = c.length; C > v; v++)
                            if (c[v].ceFalseOverride && q.is(r, c[v].selector)) return void i(r, c[v])
                    }
                }
    
                function C(e, t, n, r) {
                    function i(e) {
                        var n, r, o, a, s;
                        if (1 === e.nodeType && ie(e) && (a = b, b = "true" === ie(e), s = !0), n = ce(e.childNodes), b && !s)
                            for (r = 0, o = h.length; o > r && !O(h[r], t, e, e); r++);
                        if (m.deep && n.length) {
                            for (r = 0, o = n.length; o > r; r++) i(n[r]);
                            s && (b = a)
                        }
                    }
    
                    function o(n) {
                        var i;
                        return le(u(n.parentNode).reverse(), function(n) {
                            var o;
                            i || "_start" == n.id || "_end" == n.id || (o = w(n, e, t, r), o && o.split !== !1 && (i = n))
                        }), i
                    }
    
                    function s(e, n, r, i) {
                        var o, a, s, l, c, u;
                        if (e) {
                            for (u = e.parentNode, o = n.parentNode; o && o != u; o = o.parentNode) {
                                for (a = q.clone(o, ee), c = 0; c < h.length; c++)
                                    if (O(h[c], t, a, a)) {
                                        a = 0;
                                        break
                                    }
                                a && (s && a.appendChild(s), l || (l = a), s = a)
                            }!i || m.mixed && K(e) || (n = q.split(e, n)), s && (r.parentNode.insertBefore(s, r), l.appendChild(r))
                        }
                        return n
                    }
    
                    function c(e) {
                        return s(o(e), e, e, !0)
                    }
    
                    function d(e) {
                        var t = q.get(e ? "_start" : "_end"),
                            n = t[e ? "firstChild" : "lastChild"];
                        return se(n) && (n = n[e ? "firstChild" : "lastChild"]), 3 == n.nodeType && 0 === n.data.length && (n = e ? t.previousSibling || t.nextSibling : t.nextSibling || t.previousSibling), q.remove(t, !0), n
                    }
    
                    function f(e) {
                        var t, n, r = e.commonAncestorContainer;
                        if (e = P(e, h, te), m.split) {
                            if (t = W(e, te), n = W(e), t != n) {
                                if (/^(TR|TH|TD)$/.test(t.nodeName) && t.firstChild && (t = "TR" == t.nodeName ? t.firstChild.firstChild || t : t.firstChild || t), r && /^T(HEAD|BODY|FOOT|R)$/.test(r.nodeName) && l(n) && n.firstChild && (n = n.firstChild || n), q.isChildOf(t, n) && !K(n) && !l(t) && !l(n)) return t = L(t, "span", {
                                    id: "_start",
                                    "data-mce-type": "bookmark"
                                }), c(t), void(t = d(te));
                                t = L(t, "span", {
                                    id: "_start",
                                    "data-mce-type": "bookmark"
                                }), n = L(n, "span", {
                                    id: "_end",
                                    "data-mce-type": "bookmark"
                                }), c(t), c(n), t = d(te), n = d()
                            } else t = n = c(t);
                            e.startContainer = t.parentNode ? t.parentNode : t, e.startOffset = J(t), e.endContainer = n.parentNode ? n.parentNode : n, e.endOffset = J(n) + 1
                        }
                        Y.walk(e, function(e) {
                            le(e, function(e) {
                                i(e), 1 === e.nodeType && "underline" === a.dom.getStyle(e, "text-decoration") && e.parentNode && "underline" === v(e.parentNode) && O({
                                    deep: !1,
                                    exact: !0,
                                    inline: "span",
                                    styles: {
                                        textDecoration: "underline"
                                    }
                                }, null, e)
                            })
                        })
                    }
                    var h = p(e),
                        m = h[0],
                        g, y, b = !0;
                    if (n) return void(n.nodeType ? (y = q.createRng(), y.setStartBefore(n), y.setEndAfter(n), f(y)) : f(n));
                    if ("false" !== ie(j.getNode())) j.isCollapsed() && m.inline && !q.select("td.mce-item-selected,th.mce-item-selected").length ? V("remove", e, t, r) : (g = j.getBookmark(), f(j.getRng(te)), j.moveToBookmark(g), m.inline && E(e, t, j.getStart()) && U(j.getRng(!0)), a.nodeChanged());
                    else {
                        n = j.getNode();
                        for (var C = 0, x = h.length; x > C && (!h[C].ceFalseOverride || !O(h[C], t, n, n)); C++);
                    }
                }
    
                function x(e, t, n) {
                    var r = p(e);
                    !E(e, t, n) || "toggle" in r[0] && !r[0].toggle ? b(e, t, n) : C(e, t, n)
                }
    
                function w(e, t, n, r) {
                    function i(e, t, i) {
                        var o, a, s = t[i],
                            l;
                        if (t.onmatch) return t.onmatch(e, t, i);
                        if (s)
                            if (s.length === re) {
                                for (o in s)
                                    if (s.hasOwnProperty(o)) {
                                        if (a = "attributes" === i ? q.getAttrib(e, o) : A(e, o), r && !a && !t.exact) return;
                                        if ((!r || t.exact) && !R(a, B(D(s[o], n), o))) return
                                    }
                            } else
                                for (l = 0; l < s.length; l++)
                                    if ("attributes" === i ? q.getAttrib(e, s[l]) : A(e, s[l])) return t;
                        return t
                    }
                    var o = p(t),
                        a, s, l;
                    if (o && e)
                        for (s = 0; s < o.length; s++)
                            if (a = o[s], T(e, a) && i(e, a, "attributes") && i(e, a, "styles")) {
                                if (l = a.classes)
                                    for (s = 0; s < l.length; s++)
                                        if (!q.hasClass(e, l[s])) return;
                                return a
                            }
                }
    
                function E(e, t, n) {
                    function r(n) {
                        var r = q.getRoot();
                        return n === r ? !1 : (n = q.getParent(n, function(n) {
                            return n.parentNode === r || !!w(n, e, t, !0)
                        }), w(n, e, t))
                    }
                    var i;
                    return n ? r(n) : (n = j.getNode(), r(n) ? te : (i = j.getStart(), i != n && r(i) ? te : ee))
                }
    
                function N(e, t) {
                    var n, r = [],
                        i = {};
                    return n = j.getStart(), q.getParent(n, function(n) {
                        var o, a;
                        for (o = 0; o < e.length; o++) a = e[o], !i[a] && w(n, a, t) && (i[a] = !0, r.push(a))
                    }, q.getRoot()), r
                }
    
                function _(e) {
                    var t = p(e),
                        n, r, i, o, a;
                    if (t)
                        for (n = j.getStart(), r = u(n), o = t.length - 1; o >= 0; o--) {
                            if (a = t[o].selector, !a || t[o].defaultBlock) return te;
                            for (i = r.length - 1; i >= 0; i--)
                                if (q.is(r[i], a)) return te
                        }
                    return ee
                }
    
                function S(e, t, n) {
                    var r;
                    return ne || (ne = {}, r = {}, a.on("NodeChange", function(e) {
                        var t = u(e.element),
                            n = {};
                        t = i.grep(t, function(e) {
                            return 1 == e.nodeType && !e.getAttribute("data-mce-bogus")
                        }), le(ne, function(e, i) {
                            le(t, function(o) {
                                return w(o, i, {}, e.similar) ? (r[i] || (le(e, function(e) {
                                    e(!0, {
                                        node: o,
                                        format: i,
                                        parents: t
                                    })
                                }), r[i] = e), n[i] = e, !1) : void 0
                            })
                        }), le(r, function(i, o) {
                            n[o] || (delete r[o], le(i, function(n) {
                                n(!1, {
                                    node: e.element,
                                    format: o,
                                    parents: t
                                })
                            }))
                        })
                    })), le(e.split(","), function(e) {
                        ne[e] || (ne[e] = [], ne[e].similar = n), ne[e].push(t)
                    }), this
                }
    
                function k(e) {
                    return o.getCssText(a, e)
                }
    
                function T(e, t) {
                    return R(e, t.inline) ? te : R(e, t.block) ? te : t.selector ? 1 == e.nodeType && q.is(e, t.selector) : void 0
                }
    
                function R(e, t) {
                    return e = e || "", t = t || "", e = "" + (e.nodeName || e), t = "" + (t.nodeName || t), e.toLowerCase() == t.toLowerCase()
                }
    
                function A(e, t) {
                    return B(q.getStyle(e, t), t)
                }
    
                function B(e, t) {
                    return ("color" == t || "backgroundColor" == t) && (e = q.toHex(e)), "fontWeight" == t && 700 == e && (e = "bold"), "fontFamily" == t && (e = e.replace(/[\'\"]/g, "").replace(/,\s+/g, ",")), "" + e
                }
    
                function D(e, t) {
                    return "string" != typeof e ? e = e(t) : t && (e = e.replace(/%(\w+)/g, function(e, n) {
                        return t[n] || e
                    })), e
                }
    
                function M(e) {
                    return e && 3 === e.nodeType && /^([\t \r\n]+|)$/.test(e.nodeValue)
                }
    
                function L(e, t, n) {
                    var r = q.create(t, n);
                    return e.parentNode.insertBefore(r, e), r.appendChild(e), r
                }
    
                function P(t, n, r) {
                    function i(e) {
                        function t(e) {
                            return "BR" == e.nodeName && e.getAttribute("data-mce-bogus") && !e.nextSibling
                        }
                        var r, i, o, a, s;
                        if (r = i = e ? g : y, a = e ? "previousSibling" : "nextSibling", s = q.getRoot(), 3 == r.nodeType && !M(r) && (e ? v > 0 : b < r.nodeValue.length)) return r;
                        for (;;) {
                            if (!n[0].block_expand && K(i)) return i;
                            for (o = i[a]; o; o = o[a])
                                if (!se(o) && !M(o) && !t(o)) return i;
                            if (i == s || i.parentNode == s) {
                                r = i;
                                break
                            }
                            i = i.parentNode
                        }
                        return r
                    }
    
                    function o(e, t) {
                        for (t === re && (t = 3 === e.nodeType ? e.length : e.childNodes.length); e && e.hasChildNodes();) e = e.childNodes[t], e && (t = 3 === e.nodeType ? e.length : e.childNodes.length);
                        return {
                            node: e,
                            offset: t
                        }
                    }
    
                    function l(e) {
                        for (var t = e; t;) {
                            if (1 === t.nodeType && ie(t)) return "false" === ie(t) ? t : e;
                            t = t.parentNode
                        }
                        return e
                    }
    
                    function c(t, n, i) {
                        function o(e, t) {
                            var n, o, a = e.nodeValue;
                            return "undefined" == typeof t && (t = i ? a.length : 0), i ? (n = a.lastIndexOf(" ", t), o = a.lastIndexOf("\xa0", t), n = n > o ? n : o, -1 === n || r || n++) : (n = a.indexOf(" ", t), o = a.indexOf("\xa0", t), n = -1 !== n && (-1 === o || o > n) ? n : o), n
                        }
                        var s, l, c, u;
                        if (3 === t.nodeType) {
                            if (c = o(t, n), -1 !== c) return {
                                container: t,
                                offset: c
                            };
                            u = t
                        }
                        for (s = new e(t, q.getParent(t, K) || a.getBody()); l = s[i ? "prev" : "next"]();)
                            if (3 === l.nodeType) {
                                if (u = l, c = o(l), -1 !== c) return {
                                    container: l,
                                    offset: c
                                }
                            } else if (K(l)) break;
                        return u ? (n = i ? 0 : u.length, {
                            container: u,
                            offset: n
                        }) : void 0
                    }
    
                    function d(e, r) {
                        var i, o, a, s;
                        for (3 == e.nodeType && 0 === e.nodeValue.length && e[r] && (e = e[r]), i = u(e), o = 0; o < i.length; o++)
                            for (a = 0; a < n.length; a++)
                                if (s = n[a], !("collapsed" in s && s.collapsed !== t.collapsed) && q.is(i[o], s.selector)) return i[o];
                        return e
                    }
    
                    function f(e, t) {
                        var r, i = q.getRoot();
                        if (n[0].wrapper || (r = q.getParent(e, n[0].block, i)), r || (r = q.getParent(3 == e.nodeType ? e.parentNode : e, function(e) {
                                return e != i && s(e)
                            })), r && n[0].wrapper && (r = u(r, "ul,ol").reverse()[0] || r), !r)
                            for (r = e; r[t] && !K(r[t]) && (r = r[t], !R(r, "br")););
                        return r || e
                    }
                    var h, p, m, g = t.startContainer,
                        v = t.startOffset,
                        y = t.endContainer,
                        b = t.endOffset;
                    if (1 == g.nodeType && g.hasChildNodes() && (h = g.childNodes.length - 1, g = g.childNodes[v > h ? h : v], 3 == g.nodeType && (v = 0)), 1 == y.nodeType && y.hasChildNodes() && (h = y.childNodes.length - 1, y = y.childNodes[b > h ? h : b - 1], 3 == y.nodeType && (b = y.nodeValue.length)), g = l(g), y = l(y), (se(g.parentNode) || se(g)) && (g = se(g) ? g : g.parentNode, g = g.nextSibling || g, 3 == g.nodeType && (v = 0)), (se(y.parentNode) || se(y)) && (y = se(y) ? y : y.parentNode, y = y.previousSibling || y, 3 == y.nodeType && (b = y.length)), n[0].inline && (t.collapsed && (m = c(g, v, !0), m && (g = m.container, v = m.offset), m = c(y, b), m && (y = m.container, b = m.offset)), p = o(y, b), p.node)) {
                        for (; p.node && 0 === p.offset && p.node.previousSibling;) p = o(p.node.previousSibling);
                        p.node && p.offset > 0 && 3 === p.node.nodeType && " " === p.node.nodeValue.charAt(p.offset - 1) && p.offset > 1 && (y = p.node, y.splitText(p.offset - 1))
                    }
                    return (n[0].inline || n[0].block_expand) && (n[0].inline && 3 == g.nodeType && 0 !== v || (g = i(!0)), n[0].inline && 3 == y.nodeType && b !== y.nodeValue.length || (y = i())), n[0].selector && n[0].expand !== ee && !n[0].inline && (g = d(g, "previousSibling"), y = d(y, "nextSibling")), (n[0].block || n[0].selector) && (g = f(g, "previousSibling"), y = f(y, "nextSibling"), n[0].block && (K(g) || (g = i(!0)), K(y) || (y = i()))), 1 == g.nodeType && (v = J(g), g = g.parentNode), 1 == y.nodeType && (b = J(y) + 1, y = y.parentNode), {
                        startContainer: g,
                        startOffset: v,
                        endContainer: y,
                        endOffset: b
                    }
                }
    
                function H(e, t) {
                    return t.links && "A" == e.tagName
                }
    
                function O(e, t, n, r) {
                    var i, o, a;
                    if (!T(n, e) && !H(n, e)) return ee;
                    if ("all" != e.remove)
                        for (le(e.styles, function(i, o) {
                                i = B(D(i, t), o), "number" == typeof o && (o = i, r = 0), (e.remove_similar || !r || R(A(r, o), i)) && q.setStyle(n, o, ""), a = 1
                            }), a && "" === q.getAttrib(n, "style") && (n.removeAttribute("style"), n.removeAttribute("data-mce-style")), le(e.attributes, function(e, i) {
                                var o;
                                if (e = D(e, t), "number" == typeof i && (i = e, r = 0), !r || R(q.getAttrib(r, i), e)) {
                                    if ("class" == i && (e = q.getAttrib(n, i), e && (o = "", le(e.split(/\s+/), function(e) {
                                            /mce\-\w+/.test(e) && (o += (o ? " " : "") + e)
                                        }), o))) return void q.setAttrib(n, i, o);
                                    "class" == i && n.removeAttribute("className"), Z.test(i) && n.removeAttribute("data-mce-" + i), n.removeAttribute(i)
                                }
                            }), le(e.classes, function(e) {
                                e = D(e, t), (!r || q.hasClass(r, e)) && q.removeClass(n, e)
                            }), o = q.getAttribs(n), i = 0; i < o.length; i++)
                            if (0 !== o[i].nodeName.indexOf("_")) return ee;
                    return "none" != e.remove ? (I(n, e), te) : void 0
                }
    
                function I(e, t) {
                    function n(e, t, n) {
                        return e = F(e, t, n), !e || "BR" == e.nodeName || K(e)
                    }
                    var r = e.parentNode,
                        i;
                    t.block && (G ? r == q.getRoot() && (t.list_block && R(e, t.list_block) || le(ce(e.childNodes), function(e) {
                        X(G, e.nodeName.toLowerCase()) ? i ? i.appendChild(e) : (i = L(e, G), q.setAttribs(i, a.settings.forced_root_block_attrs)) : i = 0
                    })) : K(e) && !K(r) && (n(e, ee) || n(e.firstChild, te, 1) || e.insertBefore(q.create("br"), e.firstChild), n(e, te) || n(e.lastChild, ee, 1) || e.appendChild(q.create("br")))), t.selector && t.inline && !R(t.inline, e) || q.remove(e, 1)
                }
    
                function F(e, t, n) {
                    if (e)
                        for (t = t ? "nextSibling" : "previousSibling", e = n ? e : e[t]; e; e = e[t])
                            if (1 == e.nodeType || !M(e)) return e
                }
    
                function z(e, t) {
                    function n(e, t) {
                        for (i = e; i; i = i[t]) {
                            if (3 == i.nodeType && 0 !== i.nodeValue.length) return e;
                            if (1 == i.nodeType && !se(i)) return i
                        }
                        return e
                    }
                    var i, o, a = new r(q);
                    if (e && t && (e = n(e, "previousSibling"), t = n(t, "nextSibling"), a.compare(e, t))) {
                        for (i = e.nextSibling; i && i != t;) o = i, i = i.nextSibling, e.appendChild(o);
                        return q.remove(t), le(ce(t.childNodes), function(t) {
                            e.appendChild(t)
                        }), e
                    }
                    return t
                }
    
                function W(t, n) {
                    var r, i, o;
                    return r = t[n ? "startContainer" : "endContainer"], i = t[n ? "startOffset" : "endOffset"], 1 == r.nodeType && (o = r.childNodes.length - 1, !n && i && i--, r = r.childNodes[i > o ? o : i]), 3 === r.nodeType && n && i >= r.nodeValue.length && (r = new e(r, a.getBody()).next() || r), 3 !== r.nodeType || n || 0 !== i || (r = new e(r, a.getBody()).prev() || r), r
                }
    
                function V(t, n, r, i) {
                    function o(e) {
                        var t = q.create("span", {
                            id: g,
                            "data-mce-bogus": !0,
                            style: v ? "color:red" : ""
                        });
                        return e && t.appendChild(a.getDoc().createTextNode(Q)), t
                    }
    
                    function l(e, t) {
                        for (; e;) {
                            if (3 === e.nodeType && e.nodeValue !== Q || e.childNodes.length > 1) return !1;
                            t && 1 === e.nodeType && t.push(e), e = e.firstChild
                        }
                        return !0
                    }
    
                    function c(e) {
                        for (; e;) {
                            if (e.id === g) return e;
                            e = e.parentNode
                        }
                    }
    
                    function u(t) {
                        var n;
                        if (t)
                            for (n = new e(t, t), t = n.current(); t; t = n.next())
                                if (3 === t.nodeType) return t
                    }
    
                    function d(e, t) {
                        var n, r;
                        if (e) r = j.getRng(!0), l(e) ? (t !== !1 && (r.setStartBefore(e), r.setEndBefore(e)), q.remove(e)) : (n = u(e), n.nodeValue.charAt(0) === Q && (n.deleteData(0, 1), r.startContainer == n && r.startOffset > 0 && r.setStart(n, r.startOffset - 1), r.endContainer == n && r.endOffset > 0 && r.setEnd(n, r.endOffset - 1)), q.remove(e, 1)), j.setRng(r);
                        else if (e = c(j.getStart()), !e)
                            for (; e = q.get(g);) d(e, !1)
                    }
    
                    function f() {
                        var e, t, i, a, s, l, d;
                        e = j.getRng(!0), a = e.startOffset, l = e.startContainer, d = l.nodeValue, t = c(j.getStart()), t && (i = u(t)), d && a > 0 && a < d.length && /\w/.test(d.charAt(a)) && /\w/.test(d.charAt(a - 1)) ? (s = j.getBookmark(), e.collapse(!0), e = P(e, p(n)), e = Y.split(e), b(n, r, e), j.moveToBookmark(s)) : (t && i.nodeValue === Q ? b(n, r, t) : (t = o(!0), i = t.firstChild, e.insertNode(t), a = 1, b(n, r, t)), j.setCursorLocation(i, a))
                    }
    
                    function h() {
                        var e = j.getRng(!0),
                            t, a, l, c, u, d, f = [],
                            h, m;
                        for (t = e.startContainer, a = e.startOffset, u = t, 3 == t.nodeType && (a != t.nodeValue.length && (c = !0), u = u.parentNode); u;) {
                            if (w(u, n, r, i)) {
                                d = u;
                                break
                            }
                            u.nextSibling && (c = !0), f.push(u), u = u.parentNode
                        }
                        if (d)
                            if (c) l = j.getBookmark(), e.collapse(!0), e = P(e, p(n), !0), e = Y.split(e), C(n, r, e), j.moveToBookmark(l);
                            else {
                                for (m = o(), u = m, h = f.length - 1; h >= 0; h--) u.appendChild(q.clone(f[h], !1)), u = u.firstChild;
                                u.appendChild(q.doc.createTextNode(Q)), u = u.firstChild;
                                var g = q.getParent(d, s);
                                g && q.isEmpty(g) ? d.parentNode.replaceChild(m, d) : q.insertAfter(m, d), j.setCursorLocation(u, 1), q.isEmpty(d) && q.remove(d)
                            }
                    }
    
                    function m() {
                        var e;
                        e = c(j.getStart()), e && !q.isEmpty(e) && ue(e, function(e) {
                            1 != e.nodeType || e.id === g || q.isEmpty(e) || q.setAttrib(e, "data-mce-bogus", null)
                        }, "childNodes")
                    }
                    var g = "_mce_caret",
                        v = a.settings.caret_debug;
                    a._hasCaretEvents || (ae = function() {
                        var e = [],
                            t;
                        if (l(c(j.getStart()), e))
                            for (t = e.length; t--;) q.setAttrib(e[t], "data-mce-bogus", "1")
                    }, oe = function(e) {
                        var t = e.keyCode;
                        d(), 8 == t && j.isCollapsed() && j.getStart().innerHTML == Q && d(c(j.getStart())), (37 == t || 39 == t) && d(c(j.getStart())), m()
                    }, a.on("SetContent", function(e) {
                        e.selection && m()
                    }), a._hasCaretEvents = !0), "apply" == t ? f() : h()
                }
    
                function U(t) {
                    var n = t.startContainer,
                        r = t.startOffset,
                        i, o, a, s, l;
                    if ((t.startContainer != t.endContainer || !c(t.startContainer.childNodes[t.startOffset])) && (3 == n.nodeType && r >= n.nodeValue.length && (r = J(n), n = n.parentNode, i = !0), 1 == n.nodeType))
                        for (s = n.childNodes, n = s[Math.min(r, s.length - 1)], o = new e(n, q.getParent(n, q.isBlock)), (r > s.length - 1 || i) && o.next(), a = o.current(); a; a = o.next())
                            if (3 == a.nodeType && !M(a)) return l = q.create("a", {
                                "data-mce-bogus": "all"
                            }, Q), a.parentNode.insertBefore(l, a), t.setStart(a, 0), j.setRng(t), void q.remove(l)
                }
                var $ = {},
                    q = a.dom,
                    j = a.selection,
                    Y = new t(q),
                    X = a.schema.isValidChild,
                    K = q.isBlock,
                    G = a.settings.forced_root_block,
                    J = q.nodeIndex,
                    Q = "\ufeff",
                    Z = /^(src|href|style)$/,
                    ee = !1,
                    te = !0,
                    ne, re, ie = q.getContentEditable,
                    oe, ae, se = n.isBookmarkNode,
                    le = i.each,
                    ce = i.grep,
                    ue = i.walk,
                    de = i.extend;
                de(this, {
                    get: p,
                    register: m,
                    unregister: g,
                    apply: b,
                    remove: C,
                    toggle: x,
                    match: E,
                    matchAll: N,
                    matchNode: w,
                    canApply: _,
                    formatChanged: S,
                    getCssText: k
                }), f(), h(), a.on("BeforeGetContent", function(e) {
                    ae && "raw" != e.format && ae()
                }), a.on("mouseup keydown", function(e) {
                    oe && oe(e)
                })
            }
        }), r(J, [I, h], function(e, t) {
            return function(e) {
                function n() {
                    return e.serializer.getTrimmedContent()
                }
    
                function r(t) {
                    e.setDirty(t)
                }
    
                function i(e) {
                    o.typing = !1, o.add({}, e)
                }
                var o = this,
                    a = 0,
                    s = [],
                    l, c, u = 0;
                return e.on("init", function() {
                    o.add()
                }), e.on("BeforeExecCommand", function(e) {
                    var t = e.command;
                    "Undo" != t && "Redo" != t && "mceRepaint" != t && o.beforeChange()
                }), e.on("ExecCommand", function(e) {
                    var t = e.command;
                    "Undo" != t && "Redo" != t && "mceRepaint" != t && i(e)
                }), e.on("ObjectResizeStart Cut", function() {
                    o.beforeChange()
                }), e.on("SaveContent ObjectResized blur", i), e.on("DragEnd", i), e.on("KeyUp", function(a) {
                    var l = a.keyCode;
                    a.isDefaultPrevented() || ((l >= 33 && 36 >= l || l >= 37 && 40 >= l || 45 == l || 13 == l || a.ctrlKey) && (i(), e.nodeChanged()), (46 == l || 8 == l || t.mac && (91 == l || 93 == l)) && e.nodeChanged(), c && o.typing && (e.isDirty() || (r(s[0] && n() != s[0].content), e.isDirty() && e.fire("change", {
                        level: s[0],
                        lastLevel: null
                    })), e.fire("TypingUndo"), c = !1, e.nodeChanged()))
                }), e.on("KeyDown", function(e) {
                    var t = e.keyCode;
                    if (!e.isDefaultPrevented()) {
                        if (t >= 33 && 36 >= t || t >= 37 && 40 >= t || 45 == t) return void(o.typing && i(e));
                        var n = e.ctrlKey && !e.altKey || e.metaKey;
                        !(16 > t || t > 20) || 224 == t || 91 == t || o.typing || n || (o.beforeChange(), o.typing = !0, o.add({}, e), c = !0)
                    }
                }), e.on("MouseDown", function(e) {
                    o.typing && i(e)
                }), e.addShortcut("meta+z", "", "Undo"), e.addShortcut("meta+y,meta+shift+z", "", "Redo"), e.on("AddUndo Undo Redo ClearUndos", function(t) {
                    t.isDefaultPrevented() || e.nodeChanged()
                }), o = {
                    data: s,
                    typing: !1,
                    beforeChange: function() {
                        u || (l = e.selection.getBookmark(2, !0))
                    },
                    add: function(t, i) {
                        var o, c = e.settings,
                            d;
                        if (t = t || {}, t.content = n(), u || e.removed) return null;
                        if (d = s[a], e.fire("BeforeAddUndo", {
                                level: t,
                                lastLevel: d,
                                originalEvent: i
                            }).isDefaultPrevented()) return null;
                        if (d && d.content == t.content) return null;
                        if (s[a] && (s[a].beforeBookmark = l), c.custom_undo_redo_levels && s.length > c.custom_undo_redo_levels) {
                            for (o = 0; o < s.length - 1; o++) s[o] = s[o + 1];
                            s.length--, a = s.length
                        }
                        t.bookmark = e.selection.getBookmark(2, !0), a < s.length - 1 && (s.length = a + 1), s.push(t), a = s.length - 1;
                        var f = {
                            level: t,
                            lastLevel: d,
                            originalEvent: i
                        };
                        return e.fire("AddUndo", f), a > 0 && (r(!0), e.fire("change", f)), t
                    },
                    undo: function() {
                        var t;
                        return o.typing && (o.add(), o.typing = !1), a > 0 && (t = s[--a], e.setContent(t.content, {
                            format: "raw"
                        }), e.selection.moveToBookmark(t.beforeBookmark), r(!0), e.fire("undo", {
                            level: t
                        })), t
                    },
                    redo: function() {
                        var t;
                        return a < s.length - 1 && (t = s[++a], e.setContent(t.content, {
                            format: "raw"
                        }), e.selection.moveToBookmark(t.bookmark), r(!0), e.fire("redo", {
                            level: t
                        })), t
                    },
                    clear: function() {
                        s = [], a = 0, o.typing = !1, e.fire("ClearUndos")
                    },
                    hasUndo: function() {
                        return a > 0 || o.typing && s[0] && n() != s[0].content
                    },
                    hasRedo: function() {
                        return a < s.length - 1 && !this.typing
                    },
                    transact: function(e) {
                        o.beforeChange();
                        try {
                            u++, e()
                        } finally {
                            u--
                        }
                        o.add()
                    }
                }
            }
        }), r(Q, [y, T, h], function(e, t, n) {
            var r = n.ie && n.ie < 11;
            return function(i) {
                function o(o) {
                    function h(e) {
                        return e && a.isBlock(e) && !/^(TD|TH|CAPTION|FORM)$/.test(e.nodeName) && !/^(fixed|absolute)/i.test(e.style.position) && "true" !== a.getContentEditable(e)
                    }
    
                    function p(e) {
                        return e && /^(TD|TH|CAPTION)$/.test(e.nodeName)
                    }
    
                    function m(e) {
                        var t;
                        a.isBlock(e) && (t = s.getRng(), e.appendChild(a.create("span", null, "\xa0")), s.select(e), e.lastChild.outerHTML = "", s.setRng(t))
                    }
    
                    function g(e) {
                        var t = e,
                            n = [],
                            r;
                        if (t) {
                            for (; t = t.firstChild;) {
                                if (a.isBlock(t)) return;
                                1 != t.nodeType || d[t.nodeName.toLowerCase()] || n.push(t)
                            }
                            for (r = n.length; r--;) t = n[r], !t.hasChildNodes() || t.firstChild == t.lastChild && "" === t.firstChild.nodeValue ? a.remove(t) : "A" == t.nodeName && " " === (t.innerText || t.textContent) && a.remove(t)
                        }
                    }
    
                    function v(t) {
                        function r(e) {
                            for (; e;) {
                                if (1 == e.nodeType || 3 == e.nodeType && e.data && /[\r\n\s]/.test(e.data)) return e;
                                e = e.nextSibling
                            }
                        }
                        var i, o, l, c = t,
                            u;
                        if (t) {
                            if (n.ie && n.ie < 9 && L && L.firstChild && L.firstChild == L.lastChild && "BR" == L.firstChild.tagName && a.remove(L.firstChild), /^(LI|DT|DD)$/.test(t.nodeName)) {
                                var d = r(t.firstChild);
                                d && /^(UL|OL|DL)$/.test(d.nodeName) && t.insertBefore(a.doc.createTextNode("\xa0"), t.firstChild)
                            }
                            if (l = a.createRng(), n.ie || t.normalize(), t.hasChildNodes()) {
                                for (i = new e(t, t); o = i.current();) {
                                    if (3 == o.nodeType) {
                                        l.setStart(o, 0), l.setEnd(o, 0);
                                        break
                                    }
                                    if (f[o.nodeName.toLowerCase()]) {
                                        l.setStartBefore(o), l.setEndBefore(o);
                                        break
                                    }
                                    c = o, o = i.next()
                                }
                                o || (l.setStart(c, 0), l.setEnd(c, 0))
                            } else "BR" == t.nodeName ? t.nextSibling && a.isBlock(t.nextSibling) ? ((!P || 9 > P) && (u = a.create("br"), t.parentNode.insertBefore(u, t)), l.setStartBefore(t), l.setEndBefore(t)) : (l.setStartAfter(t), l.setEndAfter(t)) : (l.setStart(t, 0), l.setEnd(t, 0));
                            s.setRng(l), a.remove(u), s.scrollIntoView(t)
                        }
                    }
    
                    function y(e) {
                        var t = l.forced_root_block;
                        t && t.toLowerCase() === e.tagName.toLowerCase() && a.setAttribs(e, l.forced_root_block_attrs)
                    }
    
                    function b(e) {
                        e.innerHTML = r ? "" : '<br data-mce-bogus="1">'
                    }
    
                    function C(e) {
                        var t = D,
                            n, i, o, s = u.getTextInlineElements();
                        if (e || "TABLE" == z ? (n = a.create(e || V), y(n)) : n = L.cloneNode(!1), o = n, l.keep_styles !== !1)
                            do
                                if (s[t.nodeName]) {
                                    if ("_mce_caret" == t.id) continue;
                                    i = t.cloneNode(!1), a.setAttrib(i, "id", ""), n.hasChildNodes() ? (i.appendChild(n.firstChild), n.appendChild(i)) : (o = i, n.appendChild(i))
                                }
                        while (t = t.parentNode);
                        return r || (o.innerHTML = '<br data-mce-bogus="1">'), n
                    }
    
                    function x(t) {
                        var n, r, i;
                        if (3 == D.nodeType && (t ? M > 0 : M < D.nodeValue.length)) return !1;
                        if (D.parentNode == L && U && !t) return !0;
                        if (t && 1 == D.nodeType && D == L.firstChild) return !0;
                        if ("TABLE" === D.nodeName || D.previousSibling && "TABLE" == D.previousSibling.nodeName) return U && !t || !U && t;
                        for (n = new e(D, L), 3 == D.nodeType && (t && 0 === M ? n.prev() : t || M != D.nodeValue.length || n.next()); r = n.current();) {
                            if (1 === r.nodeType) {
                                if (!r.getAttribute("data-mce-bogus") && (i = r.nodeName.toLowerCase(), d[i] && "br" !== i)) return !1
                            } else if (3 === r.nodeType && !/^[ \t\r\n]*$/.test(r.nodeValue)) return !1;
                            t ? n.prev() : n.next()
                        }
                        return !0
                    }
    
                    function w(e, t) {
                        var n, r, o, s, l, c, d = V || "P";
                        if (r = a.getParent(e, a.isBlock), !r || !h(r)) {
                            if (r = r || B, c = r == i.getBody() || p(r) ? r.nodeName.toLowerCase() : r.parentNode.nodeName.toLowerCase(), !r.hasChildNodes()) return n = a.create(d), y(n), r.appendChild(n), R.setStart(n, 0), R.setEnd(n, 0), n;
                            for (s = e; s.parentNode != r;) s = s.parentNode;
                            for (; s && !a.isBlock(s);) o = s, s = s.previousSibling;
                            if (o && u.isValidChild(c, d.toLowerCase())) {
                                for (n = a.create(d), y(n), o.parentNode.insertBefore(n, o), s = o; s && !a.isBlock(s);) l = s.nextSibling, n.appendChild(s), s = l;
                                R.setStart(e, t), R.setEnd(e, t)
                            }
                        }
                        return e
                    }
    
                    function E() {
                        function e(e) {
                            for (var t = F[e ? "firstChild" : "lastChild"]; t && 1 != t.nodeType;) t = t[e ? "nextSibling" : "previousSibling"];
                            return t === L
                        }
    
                        function t() {
                            var e = F.parentNode;
                            return /^(LI|DT|DD)$/.test(e.nodeName) ? e : F
                        }
                        if (F != i.getBody()) {
                            var n = F.parentNode.nodeName;
                            /^(OL|UL|LI)$/.test(n) && (V = "LI"), O = V ? C(V) : a.create("BR"), e(!0) && e() ? "LI" == n ? a.insertAfter(O, t()) : a.replace(O, F) : e(!0) ? "LI" == n ? (a.insertAfter(O, t()), O.appendChild(a.doc.createTextNode(" ")), O.appendChild(F)) : F.parentNode.insertBefore(O, F) : e() ? (a.insertAfter(O, t()), m(O)) : (F = t(), A = R.cloneRange(), A.setStartAfter(L), A.setEndAfter(F), I = A.extractContents(), "LI" == V && "LI" == I.firstChild.nodeName ? (O = I.firstChild, a.insertAfter(I, F)) : (a.insertAfter(I, F), a.insertAfter(O, F))), a.remove(L), v(O), c.add()
                        }
                    }
    
                    function N() {
                        i.execCommand("InsertLineBreak", !1, o)
                    }
    
                    function _(e) {
                        do 3 === e.nodeType && (e.nodeValue = e.nodeValue.replace(/^[\r\n]+/, "")), e = e.firstChild; while (e)
                    }
    
                    function S(e) {
                        var t = a.getRoot(),
                            n, r;
                        for (n = e; n !== t && "false" !== a.getContentEditable(n);) "true" === a.getContentEditable(n) && (r = n), n = n.parentNode;
                        return n !== t ? r : t
                    }
    
                    function k(e) {
                        var t;
                        r || (e.normalize(), t = e.lastChild, (!t || /^(left|right)$/gi.test(a.getStyle(t, "float", !0))) && a.add(e, "br"))
                    }
    
                    function T() {
                        O = /^(H[1-6]|PRE|FIGURE)$/.test(z) && "HGROUP" != W ? C(V) : C(), l.end_container_on_empty_block && h(F) && a.isEmpty(L) ? O = a.split(F, L) : a.insertAfter(O, L), v(O)
                    }
                    var R, A, B, D, M, L, P, H, O, I, F, z, W, V, U;
                    if (R = s.getRng(!0), !o.isDefaultPrevented()) {
                        if (!R.collapsed) return void i.execCommand("Delete");
                        if (new t(a).normalize(R), D = R.startContainer, M = R.startOffset, V = (l.force_p_newlines ? "p" : "") || l.forced_root_block, V = V ? V.toUpperCase() : "", P = a.doc.documentMode, H = o.shiftKey, 1 == D.nodeType && D.hasChildNodes() && (U = M > D.childNodes.length - 1, D = D.childNodes[Math.min(M, D.childNodes.length - 1)] || D, M = U && 3 == D.nodeType ? D.nodeValue.length : 0), B = S(D)) {
                            if (c.beforeChange(), !a.isBlock(B) && B != a.getRoot()) return void((!V || H) && N());
                            if ((V && !H || !V && H) && (D = w(D, M)), L = a.getParent(D, a.isBlock), F = L ? a.getParent(L.parentNode, a.isBlock) : null, z = L ? L.nodeName.toUpperCase() : "", W = F ? F.nodeName.toUpperCase() : "", "LI" != W || o.ctrlKey || (L = F, z = W), /^(LI|DT|DD)$/.test(z)) {
                                if (!V && H) return void N();
                                if (a.isEmpty(L)) return void E()
                            }
                            if ("PRE" == z && l.br_in_pre !== !1) {
                                if (!H) return void N()
                            } else if (!V && !H && "LI" != z || V && H) return void N();
                            V && L === i.getBody() || (V = V || "P", x() ? T() : x(!0) ? (O = L.parentNode.insertBefore(C(), L), m(O), v(L)) : (A = R.cloneRange(), A.setEndAfter(L), I = A.extractContents(), _(I), O = I.firstChild, a.insertAfter(I, L), g(O), k(L), a.isEmpty(L) && b(L), O.normalize(), a.isEmpty(O) ? (a.remove(O), T()) : v(O)), a.setAttrib(O, "id", ""), i.fire("NewBlock", {
                                newBlock: O
                            }), c.add())
                        }
                    }
                }
                var a = i.dom,
                    s = i.selection,
                    l = i.settings,
                    c = i.undoManager,
                    u = i.schema,
                    d = u.getNonEmptyElements(),
                    f = u.getMoveCaretBeforeOnEnterElements();
                i.on("keydown", function(e) {
                    13 == e.keyCode && o(e) !== !1 && e.preventDefault()
                })
            }
        }), r(Z, [], function() {
            return function(e) {
                function t() {
                    var t = i.getStart(),
                        s = e.getBody(),
                        l, c, u, d, f, h, p, m = -16777215,
                        g, v, y, b, C;
                    if (C = n.forced_root_block, t && 1 === t.nodeType && C) {
                        for (; t && t != s;) {
                            if (a[t.nodeName]) return;
                            t = t.parentNode
                        }
                        if (l = i.getRng(), l.setStart) {
                            c = l.startContainer, u = l.startOffset, d = l.endContainer, f = l.endOffset;
                            try {
                                v = e.getDoc().activeElement === s
                            } catch (x) {}
                        } else l.item && (t = l.item(0), l = e.getDoc().body.createTextRange(), l.moveToElementText(t)), v = l.parentElement().ownerDocument === e.getDoc(), y = l.duplicate(), y.collapse(!0), u = -1 * y.move("character", m), y.collapsed || (y = l.duplicate(), y.collapse(!1), f = -1 * y.move("character", m) - u);
                        for (t = s.firstChild, b = s.nodeName.toLowerCase(); t;)
                            if ((3 === t.nodeType || 1 == t.nodeType && !a[t.nodeName]) && o.isValidChild(b, C.toLowerCase())) {
                                if (3 === t.nodeType && 0 === t.nodeValue.length) {
                                    p = t, t = t.nextSibling, r.remove(p);
                                    continue
                                }
                                h || (h = r.create(C, e.settings.forced_root_block_attrs), t.parentNode.insertBefore(h, t), g = !0), p = t, t = t.nextSibling, h.appendChild(p)
                            } else h = null, t = t.nextSibling;
                        if (g && v) {
                            if (l.setStart) l.setStart(c, u), l.setEnd(d, f), i.setRng(l);
                            else try {
                                l = e.getDoc().body.createTextRange(), l.moveToElementText(s), l.collapse(!0), l.moveStart("character", u), f > 0 && l.moveEnd("character", f), l.select()
                            } catch (x) {}
                            e.nodeChanged()
                        }
                    }
                }
                var n = e.settings,
                    r = e.dom,
                    i = e.selection,
                    o = e.schema,
                    a = o.getBlockElements();
                n.forced_root_block && e.on("NodeChange", t)
            }
        }), r(ee, [P, h, m, X, T, y], function(e, n, r, i, o, a) {
            var s = r.each,
                l = r.extend,
                c = r.map,
                u = r.inArray,
                d = r.explode,
                f = n.ie,
                h = n.ie && n.ie < 11,
                p = !0,
                m = !1;
            return function(r) {
                function g(e, t, n, i) {
                    var o, a, l = 0;
                    if (/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(e) || i && i.skip_focus || r.focus(), i = r.fire("BeforeExecCommand", {
                            command: e,
                            ui: t,
                            value: n
                        }), i.isDefaultPrevented()) return !1;
                    if (a = e.toLowerCase(), o = M.exec[a]) return o(a, t, n), r.fire("ExecCommand", {
                        command: e,
                        ui: t,
                        value: n
                    }), !0;
                    if (s(r.plugins, function(i) {
                            return i.execCommand && i.execCommand(e, t, n) ? (r.fire("ExecCommand", {
                                command: e,
                                ui: t,
                                value: n
                            }), l = !0, !1) : void 0
                        }), l) return l;
                    if (r.theme && r.theme.execCommand && r.theme.execCommand(e, t, n)) return r.fire("ExecCommand", {
                        command: e,
                        ui: t,
                        value: n
                    }), !0;
                    try {
                        l = r.getDoc().execCommand(e, t, n)
                    } catch (c) {}
                    return l ? (r.fire("ExecCommand", {
                        command: e,
                        ui: t,
                        value: n
                    }), !0) : !1
                }
    
                function v(e) {
                    var t;
                    if (!r._isHidden()) {
                        if (e = e.toLowerCase(), t = M.state[e]) return t(e);
                        try {
                            return r.getDoc().queryCommandState(e)
                        } catch (n) {}
                        return !1
                    }
                }
    
                function y(e) {
                    var t;
                    if (!r._isHidden()) {
                        if (e = e.toLowerCase(), t = M.value[e]) return t(e);
                        try {
                            return r.getDoc().queryCommandValue(e)
                        } catch (n) {}
                    }
                }
    
                function b(e, t) {
                    t = t || "exec", s(e, function(e, n) {
                        s(n.toLowerCase().split(","), function(n) {
                            M[t][n] = e
                        })
                    })
                }
    
                function C(e, t, n) {
                    e = e.toLowerCase(), M.exec[e] = function(e, i, o, a) {
                        return t.call(n || r, i, o, a)
                    }
                }
    
                function x(e) {
                    if (e = e.toLowerCase(), M.exec[e]) return !0;
                    try {
                        return r.getDoc().queryCommandSupported(e)
                    } catch (t) {}
                    return !1
                }
    
                function w(e, t, n) {
                    e = e.toLowerCase(), M.state[e] = function() {
                        return t.call(n || r)
                    }
                }
    
                function E(e, t, n) {
                    e = e.toLowerCase(), M.value[e] = function() {
                        return t.call(n || r)
                    }
                }
    
                function N(e) {
                    return e = e.toLowerCase(), !!M.exec[e]
                }
    
                function _(e, n, i) {
                    return n === t && (n = m), i === t && (i = null), r.getDoc().execCommand(e, n, i)
                }
    
                function S(e) {
                    return D.match(e)
                }
    
                function k(e, n) {
                    D.toggle(e, n ? {
                        value: n
                    } : t), r.nodeChanged()
                }
    
                function T(e) {
                    P = B.getBookmark(e)
                }
    
                function R() {
                    B.moveToBookmark(P)
                }
                var A, B, D, M = {
                        state: {},
                        exec: {},
                        value: {}
                    },
                    L = r.settings,
                    P;
                r.on("PreInit", function() {
                    A = r.dom, B = r.selection, L = r.settings, D = r.formatter
                }), l(this, {
                    execCommand: g,
                    queryCommandState: v,
                    queryCommandValue: y,
                    queryCommandSupported: x,
                    addCommands: b,
                    addCommand: C,
                    addQueryStateHandler: w,
                    addQueryValueHandler: E,
                    hasCustomCommand: N
                }), b({
                    "mceResetDesignMode,mceBeginUndoLevel": function() {},
                    "mceEndUndoLevel,mceAddUndoLevel": function() {
                        r.undoManager.add()
                    },
                    "Cut,Copy,Paste": function(e) {
                        var t = r.getDoc(),
                            i;
                        try {
                            _(e)
                        } catch (o) {
                            i = p
                        }
                        if (i || !t.queryCommandSupported(e)) {
                            var a = r.translate("Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X/C/V keyboard shortcuts instead.");
                            n.mac && (a = a.replace(/Ctrl\+/g, "\u2318+")), r.notificationManager.open({
                                text: a,
                                type: "error"
                            })
                        }
                    },
                    unlink: function() {
                        if (B.isCollapsed()) {
                            var e = B.getNode();
                            return void("A" == e.tagName && r.dom.remove(e, !0))
                        }
                        D.remove("link")
                    },
                    "JustifyLeft,JustifyCenter,JustifyRight,JustifyFull,JustifyNone": function(e) {
                        var t = e.substring(7);
                        "full" == t && (t = "justify"), s("left,center,right,justify".split(","), function(e) {
                            t != e && D.remove("align" + e)
                        }), "none" != t && k("align" + t)
                    },
                    "InsertUnorderedList,InsertOrderedList": function(e) {
                        var t, n;
                        _(e), t = A.getParent(B.getNode(), "ol,ul"), t && (n = t.parentNode, /^(H[1-6]|P|ADDRESS|PRE)$/.test(n.nodeName) && (T(), A.split(n, t), R()))
                    },
                    "Bold,Italic,Underline,Strikethrough,Superscript,Subscript": function(e) {
                        k(e)
                    },
                    "ForeColor,HiliteColor,FontName": function(e, t, n) {
                        k(e, n)
                    },
                    FontSize: function(e, t, n) {
                        var r, i;
                        n >= 1 && 7 >= n && (i = d(L.font_size_style_values), r = d(L.font_size_classes), n = r ? r[n - 1] || n : i[n - 1] || n), k(e, n)
                    },
                    RemoveFormat: function(e) {
                        D.remove(e)
                    },
                    mceBlockQuote: function() {
                        k("blockquote")
                    },
                    FormatBlock: function(e, t, n) {
                        return k(n || "p")
                    },
                    mceCleanup: function() {
                        var e = B.getBookmark();
                        r.setContent(r.getContent({
                            cleanup: p
                        }), {
                            cleanup: p
                        }), B.moveToBookmark(e)
                    },
                    mceRemoveNode: function(e, t, n) {
                        var i = n || B.getNode();
                        i != r.getBody() && (T(), r.dom.remove(i, p), R())
                    },
                    mceSelectNodeDepth: function(e, t, n) {
                        var i = 0;
                        A.getParent(B.getNode(), function(e) {
                            return 1 == e.nodeType && i++ == n ? (B.select(e), m) : void 0
                        }, r.getBody())
                    },
                    mceSelectNode: function(e, t, n) {
                        B.select(n)
                    },
                    mceInsertContent: function(t, n, o) {
                        function a(e) {
                            function t(e) {
                                return r[e] && 3 == r[e].nodeType
                            }
                            var n, r, i;
                            return n = B.getRng(!0), r = n.startContainer, i = n.startOffset, 3 == r.nodeType && (i > 0 ? e = e.replace(/^&nbsp;/, " ") : t("previousSibling") || (e = e.replace(/^ /, "&nbsp;")), i < r.length ? e = e.replace(/&nbsp;(<br>|)$/, " ") : t("nextSibling") || (e = e.replace(/(&nbsp;| )(<br>|)$/, "&nbsp;"))), e
                        }
    
                        function l() {
                            var e, t, n;
                            e = B.getRng(!0), t = e.startContainer, n = e.startOffset, 3 == t.nodeType && e.collapsed && ("\xa0" === t.data[n] ? (t.deleteData(n, 1), /[\u00a0| ]$/.test(o) || (o += " ")) : "\xa0" === t.data[n - 1] && (t.deleteData(n - 1, 1), /[\u00a0| ]$/.test(o) || (o = " " + o)))
                        }
    
                        function c(e) {
                            if (N)
                                for (x = e.firstChild; x; x = x.walk(!0)) S[x.name] && x.attr("data-mce-new", "true")
                        }
    
                        function u() {
                            if (N) {
                                var e = r.getBody(),
                                    t = new i(A);
                                s(A.select("*[data-mce-new]"), function(n) {
                                    n.removeAttribute("data-mce-new");
                                    for (var r = n.parentNode; r && r != e; r = r.parentNode) t.compare(r, n) && A.remove(n, !0)
                                })
                            }
                        }
    
                        function d(e) {
                            function t(e) {
                                for (var t = r.getBody(); e && e !== t; e = e.parentNode)
                                    if ("false" === r.dom.getContentEditable(e)) return e;
                                return null
                            }
                            var n;
                            if (e) {
                                if (B.scrollIntoView(e), n = t(e)) return A.remove(e), void B.select(n);
                                C = A.createRng(), x = e.previousSibling, x && 3 == x.nodeType ? (C.setStart(x, x.nodeValue.length), f || (w = e.nextSibling, w && 3 == w.nodeType && (x.appendData(w.data), w.parentNode.removeChild(w)))) : (C.setStartBefore(e), C.setEndBefore(e)), A.remove(e), B.setRng(C)
                            }
                        }
                        var h, p, m, g, v, y, b, C, x, w, E, N, _, S = r.schema.getTextInlineElements();
                        "string" != typeof o && (N = o.merge, _ = o.data, o = o.content), /^ | $/.test(o) && (o = a(o)), h = r.parser, p = new e({
                            validate: L.validate
                        }, r.schema), E = '<span id="mce_marker" data-mce-type="bookmark">&#xFEFF;&#x200B;</span>', y = {
                            content: o,
                            format: "html",
                            selection: !0
                        }, r.fire("BeforeSetContent", y), o = y.content, -1 == o.indexOf("{$caret}") && (o += "{$caret}"), o = o.replace(/\{\$caret\}/, E), C = B.getRng();
                        var k = C.startContainer || (C.parentElement ? C.parentElement() : null),
                            T = r.getBody();
                        k === T && B.isCollapsed() && A.isBlock(T.firstChild) && A.isEmpty(T.firstChild) && (C = A.createRng(), C.setStart(T.firstChild, 0), C.setEnd(T.firstChild, 0), B.setRng(C)), B.isCollapsed() || (r.selection.setRng(r.selection.getRng()), r.getDoc().execCommand("Delete", !1, null), l()), m = B.getNode();
                        var R = {
                            context: m.nodeName.toLowerCase(),
                            data: _
                        };
                        if (v = h.parse(o, R), c(v), x = v.lastChild, "mce_marker" == x.attr("id"))
                            for (b = x, x = x.prev; x; x = x.walk(!0))
                                if (3 == x.type || !A.isBlock(x.name)) {
                                    r.schema.isValidChild(x.parent.name, "span") && x.parent.insert(b, x, "br" === x.name);
                                    break
                                }
                        if (r._selectionOverrides.showBlockCaretContainer(m), R.invalid) {
                            for (B.setContent(E), m = B.getNode(), g = r.getBody(), 9 == m.nodeType ? m = x = g : x = m; x !== g;) m = x, x = x.parentNode;
                            o = m == g ? g.innerHTML : A.getOuterHTML(m), o = p.serialize(h.parse(o.replace(/<span (id="mce_marker"|id=mce_marker).+?<\/span>/i, function() {
                                return p.serialize(v)
                            }))), m == g ? A.setHTML(g, o) : A.setOuterHTML(m, o)
                        } else o = p.serialize(v), x = m.firstChild, w = m.lastChild, !x || x === w && "BR" === x.nodeName ? A.setHTML(m, o) : B.setContent(o);
                        u(), d(A.get("mce_marker")), r.fire("SetContent", y), r.addVisual()
                    },
                    mceInsertRawHTML: function(e, t, n) {
                        B.setContent("tiny_mce_marker"), r.setContent(r.getContent().replace(/tiny_mce_marker/g, function() {
                            return n
                        }))
                    },
                    mceToggleFormat: function(e, t, n) {
                        k(n)
                    },
                    mceSetContent: function(e, t, n) {
                        r.setContent(n)
                    },
                    "Indent,Outdent": function(e) {
                        var t, n, i;
                        t = L.indentation, n = /[a-z%]+$/i.exec(t), t = parseInt(t, 10), v("InsertUnorderedList") || v("InsertOrderedList") ? _(e) : (L.forced_root_block || A.getParent(B.getNode(), A.isBlock) || D.apply("div"), s(B.getSelectedBlocks(), function(o) {
                            if ("false" !== A.getContentEditable(o) && "LI" != o.nodeName) {
                                var a = r.getParam("indent_use_margin", !1) ? "margin" : "padding";
                                a += "rtl" == A.getStyle(o, "direction", !0) ? "Right" : "Left", "outdent" == e ? (i = Math.max(0, parseInt(o.style[a] || 0, 10) - t), A.setStyle(o, a, i ? i + n : "")) : (i = parseInt(o.style[a] || 0, 10) + t + n, A.setStyle(o, a, i))
                            }
                        }))
                    },
                    mceRepaint: function() {},
                    InsertHorizontalRule: function() {
                        r.execCommand("mceInsertContent", !1, "<hr />")
                    },
                    mceToggleVisualAid: function() {
                        r.hasVisual = !r.hasVisual, r.addVisual()
                    },
                    mceReplaceContent: function(e, t, n) {
                        r.execCommand("mceInsertContent", !1, n.replace(/\{\$selection\}/g, B.getContent({
                            format: "text"
                        })))
                    },
                    mceInsertLink: function(e, t, n) {
                        var r;
                        "string" == typeof n && (n = {
                            href: n
                        }), r = A.getParent(B.getNode(), "a"), n.href = n.href.replace(" ", "%20"), r && n.href || D.remove("link"), n.href && D.apply("link", n, r)
                    },
                    selectAll: function() {
                        var e = A.getRoot(),
                            t;
                        B.getRng().setStart ? (t = A.createRng(), t.setStart(e, 0), t.setEnd(e, e.childNodes.length), B.setRng(t)) : (t = B.getRng(), t.item || (t.moveToElementText(e), t.select()))
                    },
                    "delete": function() {
                        _("Delete");
                        var e = r.getBody();
                        A.isEmpty(e) && (r.setContent(""), e.firstChild && A.isBlock(e.firstChild) ? r.selection.setCursorLocation(e.firstChild, 0) : r.selection.setCursorLocation(e, 0))
                    },
                    mceNewDocument: function() {
                        r.setContent("")
                    },
                    InsertLineBreak: function(e, t, n) {
                        function i() {
                            for (var e = new a(m, v), t, n = r.schema.getNonEmptyElements(); t = e.next();)
                                if (n[t.nodeName.toLowerCase()] || t.length > 0) return !0
                        }
                        var s = n,
                            l, c, u, d = B.getRng(!0);
                        new o(A).normalize(d);
                        var f = d.startOffset,
                            m = d.startContainer;
                        if (1 == m.nodeType && m.hasChildNodes()) {
                            var g = f > m.childNodes.length - 1;
                            m = m.childNodes[Math.min(f, m.childNodes.length - 1)] || m, f = g && 3 == m.nodeType ? m.nodeValue.length : 0
                        }
                        var v = A.getParent(m, A.isBlock),
                            y = v ? v.nodeName.toUpperCase() : "",
                            b = v ? A.getParent(v.parentNode, A.isBlock) : null,
                            C = b ? b.nodeName.toUpperCase() : "",
                            x = s && s.ctrlKey;
                        "LI" != C || x || (v = b, y = C), m && 3 == m.nodeType && f >= m.nodeValue.length && (h || i() || (l = A.create("br"), d.insertNode(l), d.setStartAfter(l), d.setEndAfter(l), c = !0)), l = A.create("br"), d.insertNode(l);
                        var w = A.doc.documentMode;
                        return h && "PRE" == y && (!w || 8 > w) && l.parentNode.insertBefore(A.doc.createTextNode("\r"), l), u = A.create("span", {}, "&nbsp;"), l.parentNode.insertBefore(u, l), B.scrollIntoView(u), A.remove(u), c ? (d.setStartBefore(l), d.setEndBefore(l)) : (d.setStartAfter(l), d.setEndAfter(l)), B.setRng(d), r.undoManager.add(), p
                    }
                }), b({
                    "JustifyLeft,JustifyCenter,JustifyRight,JustifyFull": function(e) {
                        var t = "align" + e.substring(7),
                            n = B.isCollapsed() ? [A.getParent(B.getNode(), A.isBlock)] : B.getSelectedBlocks(),
                            r = c(n, function(e) {
                                return !!D.matchNode(e, t)
                            });
                        return -1 !== u(r, p)
                    },
                    "Bold,Italic,Underline,Strikethrough,Superscript,Subscript": function(e) {
                        return S(e)
                    },
                    mceBlockQuote: function() {
                        return S("blockquote")
                    },
                    Outdent: function() {
                        var e;
                        if (L.inline_styles) {
                            if ((e = A.getParent(B.getStart(), A.isBlock)) && parseInt(e.style.paddingLeft, 10) > 0) return p;
                            if ((e = A.getParent(B.getEnd(), A.isBlock)) && parseInt(e.style.paddingLeft, 10) > 0) return p
                        }
                        return v("InsertUnorderedList") || v("InsertOrderedList") || !L.inline_styles && !!A.getParent(B.getNode(), "BLOCKQUOTE")
                    },
                    "InsertUnorderedList,InsertOrderedList": function(e) {
                        var t = A.getParent(B.getNode(), "ul,ol");
                        return t && ("insertunorderedlist" === e && "UL" === t.tagName || "insertorderedlist" === e && "OL" === t.tagName)
                    }
                }, "state"), b({
                    "FontSize,FontName": function(e) {
                        var t = 0,
                            n;
                        return (n = A.getParent(B.getNode(), "span")) && (t = "fontsize" == e ? n.style.fontSize : n.style.fontFamily.replace(/, /g, ",").replace(/[\'\"]/g, "").toLowerCase()), t
                    }
                }, "value"), b({
                    Undo: function() {
                        r.undoManager.undo()
                    },
                    Redo: function() {
                        r.undoManager.redo()
                    }
                })
            }
        }), r(te, [m], function(e) {
            function t(e, o) {
                var a = this,
                    s, l;
                if (e = r(e),
                    o = a.settings = o || {}, s = o.base_uri, /^([\w\-]+):([^\/]{2})/i.test(e) || /^\s*#/.test(e)) return void(a.source = e);
                var c = 0 === e.indexOf("//");
                0 !== e.indexOf("/") || c || (e = (s ? s.protocol || "http" : "http") + "://mce_host" + e), /^[\w\-]*:?\/\//.test(e) || (l = o.base_uri ? o.base_uri.path : new t(location.href).directory, "" === o.base_uri.protocol ? e = "//mce_host" + a.toAbsPath(l, e) : (e = /([^#?]*)([#?]?.*)/.exec(e), e = (s && s.protocol || "http") + "://mce_host" + a.toAbsPath(l, e[1]) + e[2])), e = e.replace(/@@/g, "(mce_at)"), e = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(e), n(i, function(t, n) {
                    var r = e[n];
                    r && (r = r.replace(/\(mce_at\)/g, "@@")), a[t] = r
                }), s && (a.protocol || (a.protocol = s.protocol), a.userInfo || (a.userInfo = s.userInfo), a.port || "mce_host" !== a.host || (a.port = s.port), a.host && "mce_host" !== a.host || (a.host = s.host), a.source = ""), c && (a.protocol = "")
            }
            var n = e.each,
                r = e.trim,
                i = "source protocol authority userInfo user password host port relative path directory file query anchor".split(" "),
                o = {
                    ftp: 21,
                    http: 80,
                    https: 443,
                    mailto: 25
                };
            return t.prototype = {
                setPath: function(e) {
                    var t = this;
                    e = /^(.*?)\/?(\w+)?$/.exec(e), t.path = e[0], t.directory = e[1], t.file = e[2], t.source = "", t.getURI()
                },
                toRelative: function(e) {
                    var n = this,
                        r;
                    if ("./" === e) return e;
                    if (e = new t(e, {
                            base_uri: n
                        }), "mce_host" != e.host && n.host != e.host && e.host || n.port != e.port || n.protocol != e.protocol && "" !== e.protocol) return e.getURI();
                    var i = n.getURI(),
                        o = e.getURI();
                    return i == o || "/" == i.charAt(i.length - 1) && i.substr(0, i.length - 1) == o ? i : (r = n.toRelPath(n.path, e.path), e.query && (r += "?" + e.query), e.anchor && (r += "#" + e.anchor), r)
                },
                toAbsolute: function(e, n) {
                    return e = new t(e, {
                        base_uri: this
                    }), e.getURI(n && this.isSameOrigin(e))
                },
                isSameOrigin: function(e) {
                    if (this.host == e.host && this.protocol == e.protocol) {
                        if (this.port == e.port) return !0;
                        var t = o[this.protocol];
                        if (t && (this.port || t) == (e.port || t)) return !0
                    }
                    return !1
                },
                toRelPath: function(e, t) {
                    var n, r = 0,
                        i = "",
                        o, a;
                    if (e = e.substring(0, e.lastIndexOf("/")), e = e.split("/"), n = t.split("/"), e.length >= n.length)
                        for (o = 0, a = e.length; a > o; o++)
                            if (o >= n.length || e[o] != n[o]) {
                                r = o + 1;
                                break
                            }
                    if (e.length < n.length)
                        for (o = 0, a = n.length; a > o; o++)
                            if (o >= e.length || e[o] != n[o]) {
                                r = o + 1;
                                break
                            }
                    if (1 === r) return t;
                    for (o = 0, a = e.length - (r - 1); a > o; o++) i += "../";
                    for (o = r - 1, a = n.length; a > o; o++) i += o != r - 1 ? "/" + n[o] : n[o];
                    return i
                },
                toAbsPath: function(e, t) {
                    var r, i = 0,
                        o = [],
                        a, s;
                    for (a = /\/$/.test(t) ? "/" : "", e = e.split("/"), t = t.split("/"), n(e, function(e) {
                            e && o.push(e)
                        }), e = o, r = t.length - 1, o = []; r >= 0; r--) 0 !== t[r].length && "." !== t[r] && (".." !== t[r] ? i > 0 ? i-- : o.push(t[r]) : i++);
                    return r = e.length - i, s = 0 >= r ? o.reverse().join("/") : e.slice(0, r).join("/") + "/" + o.reverse().join("/"), 0 !== s.indexOf("/") && (s = "/" + s), a && s.lastIndexOf("/") !== s.length - 1 && (s += a), s
                },
                getURI: function(e) {
                    var t, n = this;
                    return (!n.source || e) && (t = "", e || (t += n.protocol ? n.protocol + "://" : "//", n.userInfo && (t += n.userInfo + "@"), n.host && (t += n.host), n.port && (t += ":" + n.port)), n.path && (t += n.path), n.query && (t += "?" + n.query), n.anchor && (t += "#" + n.anchor), n.source = t), n.source
                }
            }, t.parseDataUri = function(e) {
                var t, n;
                return e = decodeURIComponent(e).split(","), n = /data:([^;]+)/.exec(e[0]), n && (t = n[1]), {
                    type: t,
                    data: e[1]
                }
            }, t
        }), r(ne, [m], function(e) {
            function t() {}
            var n = e.each,
                r = e.extend,
                i, o;
            return t.extend = i = function(e) {
                function t() {
                    var e, t, n, r = this;
                    if (!o && (r.init && r.init.apply(r, arguments), t = r.Mixins))
                        for (e = t.length; e--;) n = t[e], n.init && n.init.apply(r, arguments)
                }
    
                function a() {
                    return this
                }
    
                function s(e, t) {
                    return function() {
                        var n = this,
                            r = n._super,
                            i;
                        return n._super = c[e], i = t.apply(n, arguments), n._super = r, i
                    }
                }
                var l = this,
                    c = l.prototype,
                    u, d, f;
                o = !0, u = new l, o = !1, e.Mixins && (n(e.Mixins, function(t) {
                    t = t;
                    for (var n in t) "init" !== n && (e[n] = t[n])
                }), c.Mixins && (e.Mixins = c.Mixins.concat(e.Mixins))), e.Methods && n(e.Methods.split(","), function(t) {
                    e[t] = a
                }), e.Properties && n(e.Properties.split(","), function(t) {
                    var n = "_" + t;
                    e[t] = function(e) {
                        var t = this,
                            r;
                        return e !== r ? (t[n] = e, t) : t[n]
                    }
                }), e.Statics && n(e.Statics, function(e, n) {
                    t[n] = e
                }), e.Defaults && c.Defaults && (e.Defaults = r({}, c.Defaults, e.Defaults));
                for (d in e) f = e[d], "function" == typeof f && c[d] ? u[d] = s(d, f) : u[d] = f;
                return t.prototype = u, t.constructor = t, t.extend = i, t
            }, t
        }), r(re, [m], function(e) {
            function t(t) {
                function n() {
                    return !1
                }
    
                function r() {
                    return !0
                }
    
                function i(e, i) {
                    var o, s, l, c;
                    if (e = e.toLowerCase(), i = i || {}, i.type = e, i.target || (i.target = u), i.preventDefault || (i.preventDefault = function() {
                            i.isDefaultPrevented = r
                        }, i.stopPropagation = function() {
                            i.isPropagationStopped = r
                        }, i.stopImmediatePropagation = function() {
                            i.isImmediatePropagationStopped = r
                        }, i.isDefaultPrevented = n, i.isPropagationStopped = n, i.isImmediatePropagationStopped = n), t.beforeFire && t.beforeFire(i), o = d[e])
                        for (s = 0, l = o.length; l > s; s++) {
                            if (c = o[s], c.once && a(e, c.func), i.isImmediatePropagationStopped()) return i.stopPropagation(), i;
                            if (c.func.call(u, i) === !1) return i.preventDefault(), i
                        }
                    return i
                }
    
                function o(t, r, i, o) {
                    var a, s, l;
                    if (r === !1 && (r = n), r)
                        for (r = {
                                func: r
                            }, o && e.extend(r, o), s = t.toLowerCase().split(" "), l = s.length; l--;) t = s[l], a = d[t], a || (a = d[t] = [], f(t, !0)), i ? a.unshift(r) : a.push(r);
                    return c
                }
    
                function a(e, t) {
                    var n, r, i, o, a;
                    if (e)
                        for (o = e.toLowerCase().split(" "), n = o.length; n--;) {
                            if (e = o[n], r = d[e], !e) {
                                for (i in d) f(i, !1), delete d[i];
                                return c
                            }
                            if (r) {
                                if (t)
                                    for (a = r.length; a--;) r[a].func === t && (r = r.slice(0, a).concat(r.slice(a + 1)), d[e] = r);
                                else r.length = 0;
                                r.length || (f(e, !1), delete d[e])
                            }
                        } else {
                            for (e in d) f(e, !1);
                            d = {}
                        }
                    return c
                }
    
                function s(e, t, n) {
                    return o(e, t, n, {
                        once: !0
                    })
                }
    
                function l(e) {
                    return e = e.toLowerCase(), !(!d[e] || 0 === d[e].length)
                }
                var c = this,
                    u, d = {},
                    f;
                t = t || {}, u = t.scope || c, f = t.toggleEvent || n, c.fire = i, c.on = o, c.off = a, c.once = s, c.has = l
            }
            var n = e.makeMap("focus blur focusin focusout click dblclick mousedown mouseup mousemove mouseover beforepaste paste cut copy selectionchange mouseout mouseenter mouseleave wheel keydown keypress keyup input contextmenu dragstart dragend dragover draggesture dragdrop drop drag submit compositionstart compositionend compositionupdate touchstart touchend", " ");
            return t.isNative = function(e) {
                return !!n[e.toLowerCase()]
            }, t
        }), r(ie, [], function() {
            function e(e) {
                this.create = e.create
            }
            return e.create = function(t, n) {
                return new e({
                    create: function(e, r) {
                        function i(t) {
                            e.set(r, t.value)
                        }
    
                        function o(e) {
                            t.set(n, e.value)
                        }
                        var a;
                        return e.on("change:" + r, o), t.on("change:" + n, i), a = e._bindings, a || (a = e._bindings = [], e.on("destroy", function() {
                            for (var e = a.length; e--;) a[e]()
                        })), a.push(function() {
                            t.off("change:" + n, i)
                        }), t.get(n)
                    }
                })
            }, e
        }), r(oe, [re], function(e) {
            function t(t) {
                return t._eventDispatcher || (t._eventDispatcher = new e({
                    scope: t,
                    toggleEvent: function(n, r) {
                        e.isNative(n) && t.toggleNativeEvent && t.toggleNativeEvent(n, r)
                    }
                })), t._eventDispatcher
            }
            return {
                fire: function(e, n, r) {
                    var i = this;
                    if (i.removed && "remove" !== e) return n;
                    if (n = t(i).fire(e, n, r), r !== !1 && i.parent)
                        for (var o = i.parent(); o && !n.isPropagationStopped();) o.fire(e, n, !1), o = o.parent();
                    return n
                },
                on: function(e, n, r) {
                    return t(this).on(e, n, r)
                },
                off: function(e, n) {
                    return t(this).off(e, n)
                },
                once: function(e, n) {
                    return t(this).once(e, n)
                },
                hasEventListeners: function(e) {
                    return t(this).has(e)
                }
            }
        }), r(ae, [ie, oe, ne, m], function(e, t, n, r) {
            function i(e) {
                return e.nodeType > 0
            }
    
            function o(e, t) {
                var n, a;
                if (e === t) return !0;
                if (null === e || null === t) return e === t;
                if ("object" != typeof e || "object" != typeof t) return e === t;
                if (r.isArray(t)) {
                    if (e.length !== t.length) return !1;
                    for (n = e.length; n--;)
                        if (!o(e[n], t[n])) return !1
                }
                if (i(e) || i(t)) return e === t;
                a = {};
                for (n in t) {
                    if (!o(e[n], t[n])) return !1;
                    a[n] = !0
                }
                for (n in e)
                    if (!a[n] && !o(e[n], t[n])) return !1;
                return !0
            }
            return n.extend({
                Mixins: [t],
                init: function(t) {
                    var n, r;
                    t = t || {};
                    for (n in t) r = t[n], r instanceof e && (t[n] = r.create(this, n));
                    this.data = t
                },
                set: function(t, n) {
                    var r, i, a = this.data[t];
                    if (n instanceof e && (n = n.create(this, t)), "object" == typeof t) {
                        for (r in t) this.set(r, t[r]);
                        return this
                    }
                    return o(a, n) || (this.data[t] = n, i = {
                        target: this,
                        name: t,
                        value: n,
                        oldValue: a
                    }, this.fire("change:" + t, i), this.fire("change", i)), this
                },
                get: function(e) {
                    return this.data[e]
                },
                has: function(e) {
                    return e in this.data
                },
                bind: function(t) {
                    return e.create(this, t)
                },
                destroy: function() {
                    this.fire("destroy")
                }
            })
        }), r(se, [ne], function(e) {
            function t(e) {
                for (var t = [], n = e.length, r; n--;) r = e[n], r.__checked || (t.push(r), r.__checked = 1);
                for (n = t.length; n--;) delete t[n].__checked;
                return t
            }
            var n = /^([\w\\*]+)?(?:#([\w\\]+))?(?:\.([\w\\\.]+))?(?:\[\@?([\w\\]+)([\^\$\*!~]?=)([\w\\]+)\])?(?:\:(.+))?/i,
                r = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
                i = /^\s*|\s*$/g,
                o, a = e.extend({
                    init: function(e) {
                        function t(e) {
                            return e ? (e = e.toLowerCase(), function(t) {
                                return "*" === e || t.type === e
                            }) : void 0
                        }
    
                        function o(e) {
                            return e ? function(t) {
                                return t._name === e
                            } : void 0
                        }
    
                        function a(e) {
                            return e ? (e = e.split("."), function(t) {
                                for (var n = e.length; n--;)
                                    if (!t.classes.contains(e[n])) return !1;
                                return !0
                            }) : void 0
                        }
    
                        function s(e, t, n) {
                            return e ? function(r) {
                                var i = r[e] ? r[e]() : "";
                                return t ? "=" === t ? i === n : "*=" === t ? i.indexOf(n) >= 0 : "~=" === t ? (" " + i + " ").indexOf(" " + n + " ") >= 0 : "!=" === t ? i != n : "^=" === t ? 0 === i.indexOf(n) : "$=" === t ? i.substr(i.length - n.length) === n : !1 : !!n
                            } : void 0
                        }
    
                        function l(e) {
                            var t;
                            return e ? (e = /(?:not\((.+)\))|(.+)/i.exec(e), e[1] ? (t = u(e[1], []), function(e) {
                                return !d(e, t)
                            }) : (e = e[2], function(t, n, r) {
                                return "first" === e ? 0 === n : "last" === e ? n === r - 1 : "even" === e ? n % 2 === 0 : "odd" === e ? n % 2 === 1 : t[e] ? t[e]() : !1
                            })) : void 0
                        }
    
                        function c(e, r, c) {
                            function u(e) {
                                e && r.push(e)
                            }
                            var d;
                            return d = n.exec(e.replace(i, "")), u(t(d[1])), u(o(d[2])), u(a(d[3])), u(s(d[4], d[5], d[6])), u(l(d[7])), r.pseudo = !!d[7], r.direct = c, r
                        }
    
                        function u(e, t) {
                            var n = [],
                                i, o, a;
                            do
                                if (r.exec(""), o = r.exec(e), o && (e = o[3], n.push(o[1]), o[2])) {
                                    i = o[3];
                                    break
                                }
                            while (o);
                            for (i && u(i, t), e = [], a = 0; a < n.length; a++) ">" != n[a] && e.push(c(n[a], [], ">" === n[a - 1]));
                            return t.push(e), t
                        }
                        var d = this.match;
                        this._selectors = u(e, [])
                    },
                    match: function(e, t) {
                        var n, r, i, o, a, s, l, c, u, d, f, h, p;
                        for (t = t || this._selectors, n = 0, r = t.length; r > n; n++) {
                            for (a = t[n], o = a.length, p = e, h = 0, i = o - 1; i >= 0; i--)
                                for (c = a[i]; p;) {
                                    if (c.pseudo)
                                        for (f = p.parent().items(), u = d = f.length; u-- && f[u] !== p;);
                                    for (s = 0, l = c.length; l > s; s++)
                                        if (!c[s](p, u, d)) {
                                            s = l + 1;
                                            break
                                        }
                                    if (s === l) {
                                        h++;
                                        break
                                    }
                                    if (i === o - 1) break;
                                    p = p.parent()
                                }
                            if (h === o) return !0
                        }
                        return !1
                    },
                    find: function(e) {
                        function n(e, t, i) {
                            var o, a, s, l, c, u = t[i];
                            for (o = 0, a = e.length; a > o; o++) {
                                for (c = e[o], s = 0, l = u.length; l > s; s++)
                                    if (!u[s](c, o, a)) {
                                        s = l + 1;
                                        break
                                    }
                                if (s === l) i == t.length - 1 ? r.push(c) : c.items && n(c.items(), t, i + 1);
                                else if (u.direct) return;
                                c.items && n(c.items(), t, i)
                            }
                        }
                        var r = [],
                            i, s, l = this._selectors;
                        if (e.items) {
                            for (i = 0, s = l.length; s > i; i++) n(e.items(), l[i], 0);
                            s > 1 && (r = t(r))
                        }
                        return o || (o = a.Collection), new o(r)
                    }
                });
            return a
        }), r(le, [m, se, ne], function(e, t, n) {
            var r, i, o = Array.prototype.push,
                a = Array.prototype.slice;
            return i = {
                length: 0,
                init: function(e) {
                    e && this.add(e)
                },
                add: function(t) {
                    var n = this;
                    return e.isArray(t) ? o.apply(n, t) : t instanceof r ? n.add(t.toArray()) : o.call(n, t), n
                },
                set: function(e) {
                    var t = this,
                        n = t.length,
                        r;
                    for (t.length = 0, t.add(e), r = t.length; n > r; r++) delete t[r];
                    return t
                },
                filter: function(e) {
                    var n = this,
                        i, o, a = [],
                        s, l;
                    for ("string" == typeof e ? (e = new t(e), l = function(t) {
                            return e.match(t)
                        }) : l = e, i = 0, o = n.length; o > i; i++) s = n[i], l(s) && a.push(s);
                    return new r(a)
                },
                slice: function() {
                    return new r(a.apply(this, arguments))
                },
                eq: function(e) {
                    return -1 === e ? this.slice(e) : this.slice(e, +e + 1)
                },
                each: function(t) {
                    return e.each(this, t), this
                },
                toArray: function() {
                    return e.toArray(this)
                },
                indexOf: function(e) {
                    for (var t = this, n = t.length; n-- && t[n] !== e;);
                    return n
                },
                reverse: function() {
                    return new r(e.toArray(this).reverse())
                },
                hasClass: function(e) {
                    return this[0] ? this[0].classes.contains(e) : !1
                },
                prop: function(e, t) {
                    var n = this,
                        r, i;
                    return t !== r ? (n.each(function(n) {
                        n[e] && n[e](t)
                    }), n) : (i = n[0], i && i[e] ? i[e]() : void 0)
                },
                exec: function(t) {
                    var n = this,
                        r = e.toArray(arguments).slice(1);
                    return n.each(function(e) {
                        e[t] && e[t].apply(e, r)
                    }), n
                },
                remove: function() {
                    for (var e = this.length; e--;) this[e].remove();
                    return this
                },
                addClass: function(e) {
                    return this.each(function(t) {
                        t.classes.add(e)
                    })
                },
                removeClass: function(e) {
                    return this.each(function(t) {
                        t.classes.remove(e)
                    })
                }
            }, e.each("fire on off show hide append prepend before after reflow".split(" "), function(t) {
                i[t] = function() {
                    var n = e.toArray(arguments);
                    return this.each(function(e) {
                        t in e && e[t].apply(e, n)
                    }), this
                }
            }), e.each("text name disabled active selected checked visible parent value data".split(" "), function(e) {
                i[e] = function(t) {
                    return this.prop(e, t)
                }
            }), r = n.extend(i), t.Collection = r, r
        }), r(ce, [m, w], function(e, t) {
            var n = 0;
            return {
                id: function() {
                    return "mceu_" + n++
                },
                createFragment: function(e) {
                    return t.DOM.createFragment(e)
                },
                getWindowSize: function() {
                    return t.DOM.getViewPort()
                },
                getSize: function(e) {
                    var t, n;
                    if (e.getBoundingClientRect) {
                        var r = e.getBoundingClientRect();
                        t = Math.max(r.width || r.right - r.left, e.offsetWidth), n = Math.max(r.height || r.bottom - r.bottom, e.offsetHeight)
                    } else t = e.offsetWidth, n = e.offsetHeight;
                    return {
                        width: t,
                        height: n
                    }
                },
                getPos: function(e, n) {
                    return t.DOM.getPos(e, n)
                },
                getViewPort: function(e) {
                    return t.DOM.getViewPort(e)
                },
                get: function(e) {
                    return document.getElementById(e)
                },
                addClass: function(e, n) {
                    return t.DOM.addClass(e, n)
                },
                removeClass: function(e, n) {
                    return t.DOM.removeClass(e, n)
                },
                hasClass: function(e, n) {
                    return t.DOM.hasClass(e, n)
                },
                toggleClass: function(e, n, r) {
                    return t.DOM.toggleClass(e, n, r)
                },
                css: function(e, n, r) {
                    return t.DOM.setStyle(e, n, r)
                },
                getRuntimeStyle: function(e, n) {
                    return t.DOM.getStyle(e, n, !0)
                },
                on: function(e, n, r, i) {
                    return t.DOM.bind(e, n, r, i)
                },
                off: function(e, n, r) {
                    return t.DOM.unbind(e, n, r)
                },
                fire: function(e, n, r) {
                    return t.DOM.fire(e, n, r)
                },
                innerHtml: function(e, n) {
                    t.DOM.setHTML(e, n)
                }
            }
        }), r(ue, [], function() {
            return {
                parseBox: function(e) {
                    var t, n = 10;
                    if (e) return "number" == typeof e ? (e = e || 0, {
                        top: e,
                        left: e,
                        bottom: e,
                        right: e
                    }) : (e = e.split(" "), t = e.length, 1 === t ? e[1] = e[2] = e[3] = e[0] : 2 === t ? (e[2] = e[0], e[3] = e[1]) : 3 === t && (e[3] = e[1]), {
                        top: parseInt(e[0], n) || 0,
                        right: parseInt(e[1], n) || 0,
                        bottom: parseInt(e[2], n) || 0,
                        left: parseInt(e[3], n) || 0
                    })
                },
                measureBox: function(e, t) {
                    function n(t) {
                        var n = document.defaultView;
                        return n ? (t = t.replace(/[A-Z]/g, function(e) {
                            return "-" + e
                        }), n.getComputedStyle(e, null).getPropertyValue(t)) : e.currentStyle[t]
                    }
    
                    function r(e) {
                        var t = parseFloat(n(e), 10);
                        return isNaN(t) ? 0 : t
                    }
                    return {
                        top: r(t + "TopWidth"),
                        right: r(t + "RightWidth"),
                        bottom: r(t + "BottomWidth"),
                        left: r(t + "LeftWidth")
                    }
                }
            }
        }), r(de, [m], function(e) {
            function t() {}
    
            function n(e) {
                this.cls = [], this.cls._map = {}, this.onchange = e || t, this.prefix = ""
            }
            return e.extend(n.prototype, {
                add: function(e) {
                    return e && !this.contains(e) && (this.cls._map[e] = !0, this.cls.push(e), this._change()), this
                },
                remove: function(e) {
                    if (this.contains(e)) {
                        for (var t = 0; t < this.cls.length && this.cls[t] !== e; t++);
                        this.cls.splice(t, 1), delete this.cls._map[e], this._change()
                    }
                    return this
                },
                toggle: function(e, t) {
                    var n = this.contains(e);
                    return n !== t && (n ? this.remove(e) : this.add(e), this._change()), this
                },
                contains: function(e) {
                    return !!this.cls._map[e]
                },
                _change: function() {
                    delete this.clsValue, this.onchange.call(this)
                }
            }), n.prototype.toString = function() {
                var e;
                if (this.clsValue) return this.clsValue;
                e = "";
                for (var t = 0; t < this.cls.length; t++) t > 0 && (e += " "), e += this.prefix + this.cls[t];
                return e
            }, n
        }), r(fe, [u], function(e) {
            var t = {},
                n;
            return {
                add: function(r) {
                    var i = r.parent();
                    if (i) {
                        if (!i._layout || i._layout.isNative()) return;
                        t[i._id] || (t[i._id] = i), n || (n = !0, e.requestAnimationFrame(function() {
                            var e, r;
                            n = !1;
                            for (e in t) r = t[e], r.state.get("rendered") && r.reflow();
                            t = {}
                        }, document.body))
                    }
                },
                remove: function(e) {
                    t[e._id] && delete t[e._id]
                }
            }
        }), r(he, [ne, m, re, ae, le, ce, g, ue, de, fe], function(e, t, n, r, i, o, a, s, l, c) {
            function u(e) {
                return e._eventDispatcher || (e._eventDispatcher = new n({
                    scope: e,
                    toggleEvent: function(t, r) {
                        r && n.isNative(t) && (e._nativeEvents || (e._nativeEvents = {}), e._nativeEvents[t] = !0, e.state.get("rendered") && d(e))
                    }
                })), e._eventDispatcher
            }
    
            function d(e) {
                function t(t) {
                    var n = e.getParentCtrl(t.target);
                    n && n.fire(t.type, t)
                }
    
                function n() {
                    var e = c._lastHoverCtrl;
                    e && (e.fire("mouseleave", {
                        target: e.getEl()
                    }), e.parents().each(function(e) {
                        e.fire("mouseleave", {
                            target: e.getEl()
                        })
                    }), c._lastHoverCtrl = null)
                }
    
                function r(t) {
                    var n = e.getParentCtrl(t.target),
                        r = c._lastHoverCtrl,
                        i = 0,
                        o, a, s;
                    if (n !== r) {
                        if (c._lastHoverCtrl = n, a = n.parents().toArray().reverse(), a.push(n), r) {
                            for (s = r.parents().toArray().reverse(), s.push(r), i = 0; i < s.length && a[i] === s[i]; i++);
                            for (o = s.length - 1; o >= i; o--) r = s[o], r.fire("mouseleave", {
                                target: r.getEl()
                            })
                        }
                        for (o = i; o < a.length; o++) n = a[o], n.fire("mouseenter", {
                            target: n.getEl()
                        })
                    }
                }
    
                function i(t) {
                    t.preventDefault(), "mousewheel" == t.type ? (t.deltaY = -1 / 40 * t.wheelDelta, t.wheelDeltaX && (t.deltaX = -1 / 40 * t.wheelDeltaX)) : (t.deltaX = 0, t.deltaY = t.detail), t = e.fire("wheel", t)
                }
                var o, s, l, c, u, d;
                if (u = e._nativeEvents) {
                    for (l = e.parents().toArray(), l.unshift(e), o = 0, s = l.length; !c && s > o; o++) c = l[o]._eventsRoot;
                    for (c || (c = l[l.length - 1] || e), e._eventsRoot = c, s = o, o = 0; s > o; o++) l[o]._eventsRoot = c;
                    var p = c._delegates;
                    p || (p = c._delegates = {});
                    for (d in u) {
                        if (!u) return !1;
                        "wheel" !== d || h ? ("mouseenter" === d || "mouseleave" === d ? c._hasMouseEnter || (a(c.getEl()).on("mouseleave", n).on("mouseover", r), c._hasMouseEnter = 1) : p[d] || (a(c.getEl()).on(d, t), p[d] = !0), u[d] = !1) : f ? a(e.getEl()).on("mousewheel", i) : a(e.getEl()).on("DOMMouseScroll", i)
                    }
                }
            }
            var f = "onmousewheel" in document,
                h = !1,
                p = "mce-",
                m, g = 0,
                v = {
                    Statics: {
                        classPrefix: p
                    },
                    isRtl: function() {
                        return m.rtl
                    },
                    classPrefix: p,
                    init: function(e) {
                        function n(e) {
                            var t;
                            for (e = e.split(" "), t = 0; t < e.length; t++) i.classes.add(e[t])
                        }
                        var i = this,
                            o, c;
                        i.settings = e = t.extend({}, i.Defaults, e), i._id = e.id || "mceu_" + g++, i._aria = {
                            role: e.role
                        }, i._elmCache = {}, i.$ = a, i.state = new r({
                            visible: !0,
                            active: !1,
                            disabled: !1,
                            value: ""
                        }), i.data = new r(e.data), i.classes = new l(function() {
                            i.state.get("rendered") && (i.getEl().className = this.toString())
                        }), i.classes.prefix = i.classPrefix, o = e.classes, o && (i.Defaults && (c = i.Defaults.classes, c && o != c && n(c)), n(o)), t.each("title text name visible disabled active value".split(" "), function(t) {
                            t in e && i[t](e[t])
                        }), i.on("click", function() {
                            return i.disabled() ? !1 : void 0
                        }), i.settings = e, i.borderBox = s.parseBox(e.border), i.paddingBox = s.parseBox(e.padding), i.marginBox = s.parseBox(e.margin), e.hidden && i.hide()
                    },
                    Properties: "parent,name",
                    getContainerElm: function() {
                        return document.body
                    },
                    getParentCtrl: function(e) {
                        for (var t, n = this.getRoot().controlIdLookup; e && n && !(t = n[e.id]);) e = e.parentNode;
                        return t
                    },
                    initLayoutRect: function() {
                        var e = this,
                            t = e.settings,
                            n, r, i = e.getEl(),
                            a, l, c, u, d, f, h, p;
                        n = e.borderBox = e.borderBox || s.measureBox(i, "border"), e.paddingBox = e.paddingBox || s.measureBox(i, "padding"), e.marginBox = e.marginBox || s.measureBox(i, "margin"), p = o.getSize(i), f = t.minWidth, h = t.minHeight, c = f || p.width, u = h || p.height, a = t.width, l = t.height, d = t.autoResize, d = "undefined" != typeof d ? d : !a && !l, a = a || c, l = l || u;
                        var m = n.left + n.right,
                            g = n.top + n.bottom,
                            v = t.maxWidth || 65535,
                            y = t.maxHeight || 65535;
                        return e._layoutRect = r = {
                            x: t.x || 0,
                            y: t.y || 0,
                            w: a,
                            h: l,
                            deltaW: m,
                            deltaH: g,
                            contentW: a - m,
                            contentH: l - g,
                            innerW: a - m,
                            innerH: l - g,
                            startMinWidth: f || 0,
                            startMinHeight: h || 0,
                            minW: Math.min(c, v),
                            minH: Math.min(u, y),
                            maxW: v,
                            maxH: y,
                            autoResize: d,
                            scrollW: 0
                        }, e._lastLayoutRect = {}, r
                    },
                    layoutRect: function(e) {
                        var t = this,
                            n = t._layoutRect,
                            r, i, o, a, s, l;
                        return n || (n = t.initLayoutRect()), e ? (o = n.deltaW, a = n.deltaH, e.x !== s && (n.x = e.x), e.y !== s && (n.y = e.y), e.minW !== s && (n.minW = e.minW), e.minH !== s && (n.minH = e.minH), i = e.w, i !== s && (i = i < n.minW ? n.minW : i, i = i > n.maxW ? n.maxW : i, n.w = i, n.innerW = i - o), i = e.h, i !== s && (i = i < n.minH ? n.minH : i, i = i > n.maxH ? n.maxH : i, n.h = i, n.innerH = i - a), i = e.innerW, i !== s && (i = i < n.minW - o ? n.minW - o : i, i = i > n.maxW - o ? n.maxW - o : i, n.innerW = i, n.w = i + o), i = e.innerH, i !== s && (i = i < n.minH - a ? n.minH - a : i, i = i > n.maxH - a ? n.maxH - a : i, n.innerH = i, n.h = i + a), e.contentW !== s && (n.contentW = e.contentW), e.contentH !== s && (n.contentH = e.contentH), r = t._lastLayoutRect, (r.x !== n.x || r.y !== n.y || r.w !== n.w || r.h !== n.h) && (l = m.repaintControls, l && l.map && !l.map[t._id] && (l.push(t), l.map[t._id] = !0), r.x = n.x, r.y = n.y, r.w = n.w, r.h = n.h), t) : n
                    },
                    repaint: function() {
                        var e = this,
                            t, n, r, i, o, a, s, l, c, u;
                        c = document.createRange ? function(e) {
                            return e
                        } : Math.round, t = e.getEl().style, i = e._layoutRect, l = e._lastRepaintRect || {}, o = e.borderBox, a = o.left + o.right, s = o.top + o.bottom, i.x !== l.x && (t.left = c(i.x) + "px", l.x = i.x), i.y !== l.y && (t.top = c(i.y) + "px", l.y = i.y), i.w !== l.w && (u = c(i.w - a), t.width = (u >= 0 ? u : 0) + "px", l.w = i.w), i.h !== l.h && (u = c(i.h - s), t.height = (u >= 0 ? u : 0) + "px", l.h = i.h), e._hasBody && i.innerW !== l.innerW && (u = c(i.innerW), r = e.getEl("body"), r && (n = r.style, n.width = (u >= 0 ? u : 0) + "px"), l.innerW = i.innerW), e._hasBody && i.innerH !== l.innerH && (u = c(i.innerH), r = r || e.getEl("body"), r && (n = n || r.style, n.height = (u >= 0 ? u : 0) + "px"), l.innerH = i.innerH), e._lastRepaintRect = l, e.fire("repaint", {}, !1)
                    },
                    on: function(e, t) {
                        function n(e) {
                            var t, n;
                            return "string" != typeof e ? e : function(i) {
                                return t || r.parentsAndSelf().each(function(r) {
                                    var i = r.settings.callbacks;
                                    return i && (t = i[e]) ? (n = r, !1) : void 0
                                }), t ? t.call(n, i) : (i.action = e, void this.fire("execute", i))
                            }
                        }
                        var r = this;
                        return u(r).on(e, n(t)), r
                    },
                    off: function(e, t) {
                        return u(this).off(e, t), this
                    },
                    fire: function(e, t, n) {
                        var r = this;
                        if (t = t || {}, t.control || (t.control = r), t = u(r).fire(e, t), n !== !1 && r.parent)
                            for (var i = r.parent(); i && !t.isPropagationStopped();) i.fire(e, t, !1), i = i.parent();
                        return t
                    },
                    hasEventListeners: function(e) {
                        return u(this).has(e)
                    },
                    parents: function(e) {
                        var t = this,
                            n, r = new i;
                        for (n = t.parent(); n; n = n.parent()) r.add(n);
                        return e && (r = r.filter(e)), r
                    },
                    parentsAndSelf: function(e) {
                        return new i(this).add(this.parents(e))
                    },
                    next: function() {
                        var e = this.parent().items();
                        return e[e.indexOf(this) + 1]
                    },
                    prev: function() {
                        var e = this.parent().items();
                        return e[e.indexOf(this) - 1]
                    },
                    innerHtml: function(e) {
                        return this.$el.html(e), this
                    },
                    getEl: function(e) {
                        var t = e ? this._id + "-" + e : this._id;
                        return this._elmCache[t] || (this._elmCache[t] = a("#" + t)[0]), this._elmCache[t]
                    },
                    show: function() {
                        return this.visible(!0)
                    },
                    hide: function() {
                        return this.visible(!1)
                    },
                    focus: function() {
                        try {
                            this.getEl().focus()
                        } catch (e) {}
                        return this
                    },
                    blur: function() {
                        return this.getEl().blur(), this
                    },
                    aria: function(e, t) {
                        var n = this,
                            r = n.getEl(n.ariaTarget);
                        return "undefined" == typeof t ? n._aria[e] : (n._aria[e] = t, n.state.get("rendered") && r.setAttribute("role" == e ? e : "aria-" + e, t), n)
                    },
                    encode: function(e, t) {
                        return t !== !1 && (e = this.translate(e)), (e || "").replace(/[&<>"]/g, function(e) {
                            return "&#" + e.charCodeAt(0) + ";"
                        })
                    },
                    translate: function(e) {
                        return m.translate ? m.translate(e) : e
                    },
                    before: function(e) {
                        var t = this,
                            n = t.parent();
                        return n && n.insert(e, n.items().indexOf(t), !0), t
                    },
                    after: function(e) {
                        var t = this,
                            n = t.parent();
                        return n && n.insert(e, n.items().indexOf(t)), t
                    },
                    remove: function() {
                        var e = this,
                            t = e.getEl(),
                            n = e.parent(),
                            r, i;
                        if (e.items) {
                            var o = e.items().toArray();
                            for (i = o.length; i--;) o[i].remove()
                        }
                        n && n.items && (r = [], n.items().each(function(t) {
                            t !== e && r.push(t)
                        }), n.items().set(r), n._lastRect = null), e._eventsRoot && e._eventsRoot == e && a(t).off();
                        var s = e.getRoot().controlIdLookup;
                        return s && delete s[e._id], t && t.parentNode && t.parentNode.removeChild(t), e.state.set("rendered", !1), e.state.destroy(), e.fire("remove"), e
                    },
                    renderBefore: function(e) {
                        return a(e).before(this.renderHtml()), this.postRender(), this
                    },
                    renderTo: function(e) {
                        return a(e || this.getContainerElm()).append(this.renderHtml()), this.postRender(), this
                    },
                    preRender: function() {},
                    render: function() {},
                    renderHtml: function() {
                        return '<div id="' + this._id + '" class="' + this.classes + '"></div>'
                    },
                    postRender: function() {
                        var e = this,
                            t = e.settings,
                            n, r, i, o, s;
                        e.$el = a(e.getEl()), e.state.set("rendered", !0);
                        for (o in t) 0 === o.indexOf("on") && e.on(o.substr(2), t[o]);
                        if (e._eventsRoot) {
                            for (i = e.parent(); !s && i; i = i.parent()) s = i._eventsRoot;
                            if (s)
                                for (o in s._nativeEvents) e._nativeEvents[o] = !0
                        }
                        d(e), t.style && (n = e.getEl(), n && (n.setAttribute("style", t.style), n.style.cssText = t.style)), e.settings.border && (r = e.borderBox, e.$el.css({
                            "border-top-width": r.top,
                            "border-right-width": r.right,
                            "border-bottom-width": r.bottom,
                            "border-left-width": r.left
                        }));
                        var l = e.getRoot();
                        l.controlIdLookup || (l.controlIdLookup = {}), l.controlIdLookup[e._id] = e;
                        for (var u in e._aria) e.aria(u, e._aria[u]);
                        e.state.get("visible") === !1 && (e.getEl().style.display = "none"), e.bindStates(), e.state.on("change:visible", function(t) {
                            var n = t.value,
                                r;
                            e.state.get("rendered") && (e.getEl().style.display = n === !1 ? "none" : "", e.getEl().getBoundingClientRect()), r = e.parent(), r && (r._lastRect = null), e.fire(n ? "show" : "hide"), c.add(e)
                        }), e.fire("postrender", {}, !1)
                    },
                    bindStates: function() {},
                    scrollIntoView: function(e) {
                        function t(e, t) {
                            var n, r, i = e;
                            for (n = r = 0; i && i != t && i.nodeType;) n += i.offsetLeft || 0, r += i.offsetTop || 0, i = i.offsetParent;
                            return {
                                x: n,
                                y: r
                            }
                        }
                        var n = this.getEl(),
                            r = n.parentNode,
                            i, o, a, s, l, c, u = t(n, r);
                        return i = u.x, o = u.y, a = n.offsetWidth, s = n.offsetHeight, l = r.clientWidth, c = r.clientHeight, "end" == e ? (i -= l - a, o -= c - s) : "center" == e && (i -= l / 2 - a / 2, o -= c / 2 - s / 2), r.scrollLeft = i, r.scrollTop = o, this
                    },
                    getRoot: function() {
                        for (var e = this, t, n = []; e;) {
                            if (e.rootControl) {
                                t = e.rootControl;
                                break
                            }
                            n.push(e), t = e, e = e.parent()
                        }
                        t || (t = this);
                        for (var r = n.length; r--;) n[r].rootControl = t;
                        return t
                    },
                    reflow: function() {
                        c.remove(this);
                        var e = this.parent();
                        return e._layout && !e._layout.isNative() && e.reflow(), this
                    }
                };
            return t.each("text title visible disabled active value".split(" "), function(e) {
                v[e] = function(t) {
                    return 0 === arguments.length ? this.state.get(e) : ("undefined" != typeof t && this.state.set(e, t), this)
                }
            }), m = e.extend(v)
        }), r(pe, [], function() {
            var e = {},
                t;
            return {
                add: function(t, n) {
                    e[t.toLowerCase()] = n
                },
                has: function(t) {
                    return !!e[t.toLowerCase()]
                },
                create: function(n, r) {
                    var i, o, a;
                    if (!t) {
                        a = tinymce.ui;
                        for (o in a) e[o.toLowerCase()] = a[o];
                        t = !0
                    }
                    if ("string" == typeof n ? (r = r || {}, r.type = n) : (r = n, n = r.type), n = n.toLowerCase(), i = e[n], !i) throw new Error("Could not find control by type: " + n);
                    return i = new i(r), i.type = n, i
                }
            }
        }), r(me, [], function() {
            return function(e) {
                function t(e) {
                    return e && 1 === e.nodeType
                }
    
                function n(e) {
                    return e = e || C, t(e) ? e.getAttribute("role") : null
                }
    
                function r(e) {
                    for (var t, r = e || C; r = r.parentNode;)
                        if (t = n(r)) return t
                }
    
                function i(e) {
                    var n = C;
                    return t(n) ? n.getAttribute("aria-" + e) : void 0
                }
    
                function o(e) {
                    var t = e.tagName.toUpperCase();
                    return "INPUT" == t || "TEXTAREA" == t
                }
    
                function a(e) {
                    return o(e) && !e.hidden ? !0 : /^(button|menuitem|checkbox|tab|menuitemcheckbox|option|gridcell)$/.test(n(e)) ? !0 : !1
                }
    
                function s(e) {
                    function t(e) {
                        if (1 == e.nodeType && "none" != e.style.display) {
                            a(e) && n.push(e);
                            for (var r = 0; r < e.childNodes.length; r++) t(e.childNodes[r])
                        }
                    }
                    var n = [];
                    return t(e || b.getEl()), n
                }
    
                function l(e) {
                    var t, n;
                    e = e || x, n = e.parents().toArray(), n.unshift(e);
                    for (var r = 0; r < n.length && (t = n[r], !t.settings.ariaRoot); r++);
                    return t
                }
    
                function c(e) {
                    var t = l(e),
                        n = s(t.getEl());
                    t.settings.ariaRemember && "lastAriaIndex" in t ? u(t.lastAriaIndex, n) : u(0, n)
                }
    
                function u(e, t) {
                    return 0 > e ? e = t.length - 1 : e >= t.length && (e = 0), t[e] && t[e].focus(), e
                }
    
                function d(e, t) {
                    var n = -1,
                        r = l();
                    t = t || s(r.getEl());
                    for (var i = 0; i < t.length; i++) t[i] === C && (n = i);
                    n += e, r.lastAriaIndex = u(n, t)
                }
    
                function f() {
                    var e = r();
                    "tablist" == e ? d(-1, s(C.parentNode)) : x.parent().submenu ? v() : d(-1)
                }
    
                function h() {
                    var e = n(),
                        t = r();
                    "tablist" == t ? d(1, s(C.parentNode)) : "menuitem" == e && "menu" == t && i("haspopup") ? y() : d(1)
                }
    
                function p() {
                    d(-1)
                }
    
                function m() {
                    var e = n(),
                        t = r();
                    "menuitem" == e && "menubar" == t ? y() : "button" == e && i("haspopup") ? y({
                        key: "down"
                    }) : d(1)
                }
    
                function g(e) {
                    var t = r();
                    if ("tablist" == t) {
                        var n = s(x.getEl("body"))[0];
                        n && n.focus()
                    } else d(e.shiftKey ? -1 : 1)
                }
    
                function v() {
                    x.fire("cancel")
                }
    
                function y(e) {
                    e = e || {}, x.fire("click", {
                        target: C,
                        aria: e
                    })
                }
                var b = e.root,
                    C, x;
                try {
                    C = document.activeElement
                } catch (w) {
                    C = document.body
                }
                return x = b.getParentCtrl(C), b.on("keydown", function(e) {
                    function t(e, t) {
                        o(C) || t(e) !== !1 && e.preventDefault()
                    }
                    if (!e.isDefaultPrevented()) switch (e.keyCode) {
                        case 37:
                            t(e, f);
                            break;
                        case 39:
                            t(e, h);
                            break;
                        case 38:
                            t(e, p);
                            break;
                        case 40:
                            t(e, m);
                            break;
                        case 27:
                            v();
                            break;
                        case 14:
                        case 13:
                        case 32:
                            t(e, y);
                            break;
                        case 9:
                            g(e) !== !1 && e.preventDefault()
                    }
                }), b.on("focusin", function(e) {
                    C = e.target, x = e.control
                }), {
                    focusFirst: c
                }
            }
        }), r(ge, [he, le, se, pe, me, m, g, de, fe], function(e, t, n, r, i, o, a, s, l) {
            var c = {};
            return e.extend({
                init: function(e) {
                    var n = this;
                    n._super(e), e = n.settings, e.fixed && n.state.set("fixed", !0), n._items = new t, n.isRtl() && n.classes.add("rtl"), n.bodyClasses = new s(function() {
                        n.state.get("rendered") && (n.getEl("body").className = this.toString())
                    }), n.bodyClasses.prefix = n.classPrefix, n.classes.add("container"), n.bodyClasses.add("container-body"), e.containerCls && n.classes.add(e.containerCls), n._layout = r.create((e.layout || "") + "layout"), n.settings.items ? n.add(n.settings.items) : n.add(n.render()), n._hasBody = !0
                },
                items: function() {
                    return this._items
                },
                find: function(e) {
                    return e = c[e] = c[e] || new n(e), e.find(this)
                },
                add: function(e) {
                    var t = this;
                    return t.items().add(t.create(e)).parent(t), t
                },
                focus: function(e) {
                    var t = this,
                        n, r, i;
                    return e && (r = t.keyboardNav || t.parents().eq(-1)[0].keyboardNav) ? void r.focusFirst(t) : (i = t.find("*"), t.statusbar && i.add(t.statusbar.items()), i.each(function(e) {
                        return e.settings.autofocus ? (n = null, !1) : void(e.canFocus && (n = n || e))
                    }), n && n.focus(), t)
                },
                replace: function(e, t) {
                    for (var n, r = this.items(), i = r.length; i--;)
                        if (r[i] === e) {
                            r[i] = t;
                            break
                        }
                    i >= 0 && (n = t.getEl(), n && n.parentNode.removeChild(n), n = e.getEl(), n && n.parentNode.removeChild(n)), t.parent(this)
                },
                create: function(t) {
                    var n = this,
                        i, a = [];
                    return o.isArray(t) || (t = [t]), o.each(t, function(t) {
                        t && (t instanceof e || ("string" == typeof t && (t = {
                            type: t
                        }), i = o.extend({}, n.settings.defaults, t), t.type = i.type = i.type || t.type || n.settings.defaultType || (i.defaults ? i.defaults.type : null), t = r.create(i)), a.push(t))
                    }), a
                },
                renderNew: function() {
                    var e = this;
                    return e.items().each(function(t, n) {
                        var r;
                        t.parent(e), t.state.get("rendered") || (r = e.getEl("body"), r.hasChildNodes() && n <= r.childNodes.length - 1 ? a(r.childNodes[n]).before(t.renderHtml()) : a(r).append(t.renderHtml()), t.postRender(), l.add(t))
                    }), e._layout.applyClasses(e.items().filter(":visible")), e._lastRect = null, e
                },
                append: function(e) {
                    return this.add(e).renderNew()
                },
                prepend: function(e) {
                    var t = this;
                    return t.items().set(t.create(e).concat(t.items().toArray())), t.renderNew()
                },
                insert: function(e, t, n) {
                    var r = this,
                        i, o, a;
                    return e = r.create(e), i = r.items(), !n && t < i.length - 1 && (t += 1), t >= 0 && t < i.length && (o = i.slice(0, t).toArray(), a = i.slice(t).toArray(), i.set(o.concat(e, a))), r.renderNew()
                },
                fromJSON: function(e) {
                    var t = this;
                    for (var n in e) t.find("#" + n).value(e[n]);
                    return t
                },
                toJSON: function() {
                    var e = this,
                        t = {};
                    return e.find("*").each(function(e) {
                        var n = e.name(),
                            r = e.value();
                        n && "undefined" != typeof r && (t[n] = r)
                    }), t
                },
                renderHtml: function() {
                    var e = this,
                        t = e._layout,
                        n = this.settings.role;
                    return e.preRender(), t.preRender(e), '<div id="' + e._id + '" class="' + e.classes + '"' + (n ? ' role="' + this.settings.role + '"' : "") + '><div id="' + e._id + '-body" class="' + e.bodyClasses + '">' + (e.settings.html || "") + t.renderHtml(e) + "</div></div>"
                },
                postRender: function() {
                    var e = this,
                        t;
                    return e.items().exec("postRender"), e._super(), e._layout.postRender(e), e.state.set("rendered", !0), e.settings.style && e.$el.css(e.settings.style), e.settings.border && (t = e.borderBox, e.$el.css({
                        "border-top-width": t.top,
                        "border-right-width": t.right,
                        "border-bottom-width": t.bottom,
                        "border-left-width": t.left
                    })), e.parent() || (e.keyboardNav = new i({
                        root: e
                    })), e
                },
                initLayoutRect: function() {
                    var e = this,
                        t = e._super();
                    return e._layout.recalc(e), t
                },
                recalc: function() {
                    var e = this,
                        t = e._layoutRect,
                        n = e._lastRect;
                    return n && n.w == t.w && n.h == t.h ? void 0 : (e._layout.recalc(e), t = e.layoutRect(), e._lastRect = {
                        x: t.x,
                        y: t.y,
                        w: t.w,
                        h: t.h
                    }, !0)
                },
                reflow: function() {
                    var t;
                    if (l.remove(this), this.visible()) {
                        for (e.repaintControls = [], e.repaintControls.map = {}, this.recalc(), t = e.repaintControls.length; t--;) e.repaintControls[t].repaint();
                        "flow" !== this.settings.layout && "stack" !== this.settings.layout && this.repaint(), e.repaintControls = []
                    }
                    return this
                }
            })
        }), r(ve, [g], function(e) {
            function t(e) {
                var t, n, r, i, o, a, s, l, c = Math.max;
                return t = e.documentElement, n = e.body, r = c(t.scrollWidth, n.scrollWidth), i = c(t.clientWidth, n.clientWidth), o = c(t.offsetWidth, n.offsetWidth), a = c(t.scrollHeight, n.scrollHeight), s = c(t.clientHeight, n.clientHeight), l = c(t.offsetHeight, n.offsetHeight), {
                    width: o > r ? i : r,
                    height: l > a ? s : a
                }
            }
    
            function n(e) {
                var t, n;
                if (e.changedTouches)
                    for (t = "screenX screenY pageX pageY clientX clientY".split(" "), n = 0; n < t.length; n++) e[t[n]] = e.changedTouches[0][t[n]]
            }
            return function(r, i) {
                function o() {
                    return s.getElementById(i.handle || r)
                }
                var a, s = i.document || document,
                    l, c, u, d, f, h;
                i = i || {}, c = function(r) {
                    var c = t(s),
                        p, m;
                    n(r), r.preventDefault(), l = r.button, p = o(), f = r.screenX, h = r.screenY, m = window.getComputedStyle ? window.getComputedStyle(p, null).getPropertyValue("cursor") : p.runtimeStyle.cursor, a = e("<div>").css({
                        position: "absolute",
                        top: 0,
                        left: 0,
                        width: c.width,
                        height: c.height,
                        zIndex: 2147483647,
                        opacity: 1e-4,
                        cursor: m
                    }).appendTo(s.body), e(s).on("mousemove touchmove", d).on("mouseup touchend", u), i.start(r)
                }, d = function(e) {
                    return n(e), e.button !== l ? u(e) : (e.deltaX = e.screenX - f, e.deltaY = e.screenY - h, e.preventDefault(), void i.drag(e))
                }, u = function(t) {
                    n(t), e(s).off("mousemove touchmove", d).off("mouseup touchend", u), a.remove(), i.stop && i.stop(t)
                }, this.destroy = function() {
                    e(o()).off()
                }, e(o()).on("mousedown touchstart", c);
            }
        }), r(ye, [g, ve], function(e, t) {
            return {
                init: function() {
                    var e = this;
                    e.on("repaint", e.renderScroll)
                },
                renderScroll: function() {
                    function n() {
                        function t(t, a, s, l, c, u) {
                            var d, f, h, p, m, g, v, y, b;
                            if (f = i.getEl("scroll" + t)) {
                                if (y = a.toLowerCase(), b = s.toLowerCase(), e(i.getEl("absend")).css(y, i.layoutRect()[l] - 1), !c) return void e(f).css("display", "none");
                                e(f).css("display", "block"), d = i.getEl("body"), h = i.getEl("scroll" + t + "t"), p = d["client" + s] - 2 * o, p -= n && r ? f["client" + u] : 0, m = d["scroll" + s], g = p / m, v = {}, v[y] = d["offset" + a] + o, v[b] = p, e(f).css(v), v = {}, v[y] = d["scroll" + a] * g, v[b] = p * g, e(h).css(v)
                            }
                        }
                        var n, r, a;
                        a = i.getEl("body"), n = a.scrollWidth > a.clientWidth, r = a.scrollHeight > a.clientHeight, t("h", "Left", "Width", "contentW", n, "Height"), t("v", "Top", "Height", "contentH", r, "Width")
                    }
    
                    function r() {
                        function n(n, r, a, s, l) {
                            var c, u = i._id + "-scroll" + n,
                                d = i.classPrefix;
                            e(i.getEl()).append('<div id="' + u + '" class="' + d + "scrollbar " + d + "scrollbar-" + n + '"><div id="' + u + 't" class="' + d + 'scrollbar-thumb"></div></div>'), i.draghelper = new t(u + "t", {
                                start: function() {
                                    c = i.getEl("body")["scroll" + r], e("#" + u).addClass(d + "active")
                                },
                                drag: function(e) {
                                    var t, u, d, f, h = i.layoutRect();
                                    u = h.contentW > h.innerW, d = h.contentH > h.innerH, f = i.getEl("body")["client" + a] - 2 * o, f -= u && d ? i.getEl("scroll" + n)["client" + l] : 0, t = f / i.getEl("body")["scroll" + a], i.getEl("body")["scroll" + r] = c + e["delta" + s] / t
                                },
                                stop: function() {
                                    e("#" + u).removeClass(d + "active")
                                }
                            })
                        }
                        i.classes.add("scroll"), n("v", "Top", "Height", "Y", "Width"), n("h", "Left", "Width", "X", "Height")
                    }
                    var i = this,
                        o = 2;
                    i.settings.autoScroll && (i._hasScroll || (i._hasScroll = !0, r(), i.on("wheel", function(e) {
                        var t = i.getEl("body");
                        t.scrollLeft += 10 * (e.deltaX || 0), t.scrollTop += 10 * e.deltaY, n()
                    }), e(i.getEl("body")).on("scroll", n)), n())
                }
            }
        }), r(be, [ge, ye], function(e, t) {
            return e.extend({
                Defaults: {
                    layout: "fit",
                    containerCls: "panel"
                },
                Mixins: [t],
                renderHtml: function() {
                    var e = this,
                        t = e._layout,
                        n = e.settings.html;
                    return e.preRender(), t.preRender(e), "undefined" == typeof n ? n = '<div id="' + e._id + '-body" class="' + e.bodyClasses + '">' + t.renderHtml(e) + "</div>" : ("function" == typeof n && (n = n.call(e)), e._hasBody = !1), '<div id="' + e._id + '" class="' + e.classes + '" hidefocus="1" tabindex="-1" role="group">' + (e._preBodyHtml || "") + n + "</div>"
                }
            })
        }), r(Ce, [ce], function(e) {
            function t(t, n, r) {
                var i, o, a, s, l, c, u, d, f, h;
                return f = e.getViewPort(), o = e.getPos(n), a = o.x, s = o.y, t.state.get("fixed") && "static" == e.getRuntimeStyle(document.body, "position") && (a -= f.x, s -= f.y), i = t.getEl(), h = e.getSize(i), l = h.width, c = h.height, h = e.getSize(n), u = h.width, d = h.height, r = (r || "").split(""), "b" === r[0] && (s += d), "r" === r[1] && (a += u), "c" === r[0] && (s += Math.round(d / 2)), "c" === r[1] && (a += Math.round(u / 2)), "b" === r[3] && (s -= c), "r" === r[4] && (a -= l), "c" === r[3] && (s -= Math.round(c / 2)), "c" === r[4] && (a -= Math.round(l / 2)), {
                    x: a,
                    y: s,
                    w: l,
                    h: c
                }
            }
            return {
                testMoveRel: function(n, r) {
                    for (var i = e.getViewPort(), o = 0; o < r.length; o++) {
                        var a = t(this, n, r[o]);
                        if (this.state.get("fixed")) {
                            if (a.x > 0 && a.x + a.w < i.w && a.y > 0 && a.y + a.h < i.h) return r[o]
                        } else if (a.x > i.x && a.x + a.w < i.w + i.x && a.y > i.y && a.y + a.h < i.h + i.y) return r[o]
                    }
                    return r[0]
                },
                moveRel: function(e, n) {
                    "string" != typeof n && (n = this.testMoveRel(e, n));
                    var r = t(this, e, n);
                    return this.moveTo(r.x, r.y)
                },
                moveBy: function(e, t) {
                    var n = this,
                        r = n.layoutRect();
                    return n.moveTo(r.x + e, r.y + t), n
                },
                moveTo: function(t, n) {
                    function r(e, t, n) {
                        return 0 > e ? 0 : e + n > t ? (e = t - n, 0 > e ? 0 : e) : e
                    }
                    var i = this;
                    if (i.settings.constrainToViewport) {
                        var o = e.getViewPort(window),
                            a = i.layoutRect();
                        t = r(t, o.w + o.x, a.w), n = r(n, o.h + o.y, a.h)
                    }
                    return i.state.get("rendered") ? i.layoutRect({
                        x: t,
                        y: n
                    }).repaint() : (i.settings.x = t, i.settings.y = n), i.fire("move", {
                        x: t,
                        y: n
                    }), i
                }
            }
        }), r(xe, [ce], function(e) {
            return {
                resizeToContent: function() {
                    this._layoutRect.autoResize = !0, this._lastRect = null, this.reflow()
                },
                resizeTo: function(t, n) {
                    if (1 >= t || 1 >= n) {
                        var r = e.getWindowSize();
                        t = 1 >= t ? t * r.w : t, n = 1 >= n ? n * r.h : n
                    }
                    return this._layoutRect.autoResize = !1, this.layoutRect({
                        minW: t,
                        minH: n,
                        w: t,
                        h: n
                    }).reflow()
                },
                resizeBy: function(e, t) {
                    var n = this,
                        r = n.layoutRect();
                    return n.resizeTo(r.w + e, r.h + t)
                }
            }
        }), r(we, [be, Ce, xe, ce, g, u], function(e, t, n, r, i, o) {
            function a(e, t) {
                for (; e;) {
                    if (e == t) return !0;
                    e = e.parent()
                }
            }
    
            function s(e) {
                for (var t = v.length; t--;) {
                    var n = v[t],
                        r = n.getParentCtrl(e.target);
                    if (n.settings.autohide) {
                        if (r && (a(r, n) || n.parent() === r)) continue;
                        e = n.fire("autohide", {
                            target: e.target
                        }), e.isDefaultPrevented() || n.hide()
                    }
                }
            }
    
            function l() {
                p || (p = function(e) {
                    2 != e.button && s(e)
                }, i(document).on("click touchstart", p))
            }
    
            function c() {
                m || (m = function() {
                    var e;
                    for (e = v.length; e--;) d(v[e])
                }, i(window).on("scroll", m))
            }
    
            function u() {
                if (!g) {
                    var e = document.documentElement,
                        t = e.clientWidth,
                        n = e.clientHeight;
                    g = function() {
                        document.all && t == e.clientWidth && n == e.clientHeight || (t = e.clientWidth, n = e.clientHeight, C.hideAll())
                    }, i(window).on("resize", g)
                }
            }
    
            function d(e) {
                function t(t, n) {
                    for (var r, i = 0; i < v.length; i++)
                        if (v[i] != e)
                            for (r = v[i].parent(); r && (r = r.parent());) r == e && v[i].fixed(t).moveBy(0, n).repaint()
                }
                var n = r.getViewPort().y;
                e.settings.autofix && (e.state.get("fixed") ? e._autoFixY > n && (e.fixed(!1).layoutRect({
                    y: e._autoFixY
                }).repaint(), t(!1, e._autoFixY - n)) : (e._autoFixY = e.layoutRect().y, e._autoFixY < n && (e.fixed(!0).layoutRect({
                    y: 0
                }).repaint(), t(!0, n - e._autoFixY))))
            }
    
            function f(e, t) {
                var n, r = C.zIndex || 65535,
                    o;
                if (e) y.push(t);
                else
                    for (n = y.length; n--;) y[n] === t && y.splice(n, 1);
                if (y.length)
                    for (n = 0; n < y.length; n++) y[n].modal && (r++, o = y[n]), y[n].getEl().style.zIndex = r, y[n].zIndex = r, r++;
                var a = document.getElementById(t.classPrefix + "modal-block");
                o ? i(a).css("z-index", o.zIndex - 1) : a && (a.parentNode.removeChild(a), b = !1), C.currentZIndex = r
            }
    
            function h(e) {
                var t;
                for (t = v.length; t--;) v[t] === e && v.splice(t, 1);
                for (t = y.length; t--;) y[t] === e && y.splice(t, 1)
            }
            var p, m, g, v = [],
                y = [],
                b, C = e.extend({
                    Mixins: [t, n],
                    init: function(e) {
                        var t = this;
                        t._super(e), t._eventsRoot = t, t.classes.add("floatpanel"), e.autohide && (l(), u(), v.push(t)), e.autofix && (c(), t.on("move", function() {
                            d(this)
                        })), t.on("postrender show", function(e) {
                            if (e.control == t) {
                                var n, r = t.classPrefix;
                                t.modal && !b && (n = i("#" + r + "modal-block"), n[0] || (n = i('<div id="' + r + 'modal-block" class="' + r + "reset " + r + 'fade"></div>').appendTo(t.getContainerElm())), o.setTimeout(function() {
                                    n.addClass(r + "in"), i(t.getEl()).addClass(r + "in")
                                }), b = !0), f(!0, t)
                            }
                        }), t.on("show", function() {
                            t.parents().each(function(e) {
                                return e.state.get("fixed") ? (t.fixed(!0), !1) : void 0
                            })
                        }), e.popover && (t._preBodyHtml = '<div class="' + t.classPrefix + 'arrow"></div>', t.classes.add("popover").add("bottom").add(t.isRtl() ? "end" : "start"))
                    },
                    fixed: function(e) {
                        var t = this;
                        if (t.state.get("fixed") != e) {
                            if (t.state.get("rendered")) {
                                var n = r.getViewPort();
                                e ? t.layoutRect().y -= n.y : t.layoutRect().y += n.y
                            }
                            t.classes.toggle("fixed", e), t.state.set("fixed", e)
                        }
                        return t
                    },
                    show: function() {
                        var e = this,
                            t, n = e._super();
                        for (t = v.length; t-- && v[t] !== e;);
                        return -1 === t && v.push(e), n
                    },
                    hide: function() {
                        return h(this), f(!1, this), this._super()
                    },
                    hideAll: function() {
                        C.hideAll()
                    },
                    close: function() {
                        var e = this;
                        return e.fire("close").isDefaultPrevented() || (e.remove(), f(!1, e)), e
                    },
                    remove: function() {
                        h(this), this._super()
                    },
                    postRender: function() {
                        var e = this;
                        return e.settings.bodyRole && this.getEl("body").setAttribute("role", e.settings.bodyRole), e._super()
                    }
                });
            return C.hideAll = function() {
                for (var e = v.length; e--;) {
                    var t = v[e];
                    t && t.settings.autohide && (t.hide(), v.splice(e, 1))
                }
            }, C
        }), r(Ee, [we, be, ce, g, ve, ue, h, u], function(e, t, n, r, i, o, a, s) {
            function l(e) {
                var t = "width=device-width,initial-scale=1.0,user-scalable=0,minimum-scale=1.0,maximum-scale=1.0",
                    n = r("meta[name=viewport]")[0],
                    i;
                a.overrideViewPort !== !1 && (n || (n = document.createElement("meta"), n.setAttribute("name", "viewport"), document.getElementsByTagName("head")[0].appendChild(n)), i = n.getAttribute("content"), i && "undefined" != typeof f && (f = i), n.setAttribute("content", e ? t : f))
            }
    
            function c(e) {
                for (var t = 0; t < d.length; t++)
                    if (d[t]._fullscreen) return;
                r([document.documentElement, document.body]).removeClass(e + "fullscreen")
            }
    
            function u() {
                function e() {
                    var e, t = n.getWindowSize(),
                        r;
                    for (e = 0; e < d.length; e++) r = d[e].layoutRect(), d[e].moveTo(d[e].settings.x || Math.max(0, t.w / 2 - r.w / 2), d[e].settings.y || Math.max(0, t.h / 2 - r.h / 2))
                }
                var t = {
                    w: window.innerWidth,
                    h: window.innerHeight
                };
                s.setInterval(function() {
                    var e = window.innerWidth,
                        n = window.innerHeight;
                    (t.w != e || t.h != n) && (t = {
                        w: e,
                        h: n
                    }, r(window).trigger("resize"))
                }, 100), r(window).on("resize", e)
            }
            var d = [],
                f = "",
                h = e.extend({
                    modal: !0,
                    Defaults: {
                        border: 1,
                        layout: "flex",
                        containerCls: "panel",
                        role: "dialog",
                        callbacks: {
                            submit: function() {
                                this.fire("submit", {
                                    data: this.toJSON()
                                })
                            },
                            close: function() {
                                this.close()
                            }
                        }
                    },
                    init: function(e) {
                        var n = this;
                        n._super(e), n.isRtl() && n.classes.add("rtl"), n.classes.add("window"), n.bodyClasses.add("window-body"), n.state.set("fixed", !0), e.buttons && (n.statusbar = new t({
                            layout: "flex",
                            border: "1 0 0 0",
                            spacing: 3,
                            padding: 10,
                            align: "center",
                            pack: n.isRtl() ? "start" : "end",
                            defaults: {
                                type: "button"
                            },
                            items: e.buttons
                        }), n.statusbar.classes.add("foot"), n.statusbar.parent(n)), n.on("click", function(e) {
                            -1 != e.target.className.indexOf(n.classPrefix + "close") && n.close()
                        }), n.on("cancel", function() {
                            n.close()
                        }), n.aria("describedby", n.describedBy || n._id + "-none"), n.aria("label", e.title), n._fullscreen = !1
                    },
                    recalc: function() {
                        var e = this,
                            t = e.statusbar,
                            r, i, o, a;
                        e._fullscreen && (e.layoutRect(n.getWindowSize()), e.layoutRect().contentH = e.layoutRect().innerH), e._super(), r = e.layoutRect(), e.settings.title && !e._fullscreen && (i = r.headerW, i > r.w && (o = r.x - Math.max(0, i / 2), e.layoutRect({
                            w: i,
                            x: o
                        }), a = !0)), t && (t.layoutRect({
                            w: e.layoutRect().innerW
                        }).recalc(), i = t.layoutRect().minW + r.deltaW, i > r.w && (o = r.x - Math.max(0, i - r.w), e.layoutRect({
                            w: i,
                            x: o
                        }), a = !0)), a && e.recalc()
                    },
                    initLayoutRect: function() {
                        var e = this,
                            t = e._super(),
                            r = 0,
                            i;
                        if (e.settings.title && !e._fullscreen) {
                            i = e.getEl("head");
                            var o = n.getSize(i);
                            t.headerW = o.width, t.headerH = o.height, r += t.headerH
                        }
                        e.statusbar && (r += e.statusbar.layoutRect().h), t.deltaH += r, t.minH += r, t.h += r;
                        var a = n.getWindowSize();
                        return t.x = e.settings.x || Math.max(0, a.w / 2 - t.w / 2), t.y = e.settings.y || Math.max(0, a.h / 2 - t.h / 2), t
                    },
                    renderHtml: function() {
                        var e = this,
                            t = e._layout,
                            n = e._id,
                            r = e.classPrefix,
                            i = e.settings,
                            o = "",
                            a = "",
                            s = i.html;
                        return e.preRender(), t.preRender(e), i.title && (o = '<div id="' + n + '-head" class="' + r + 'window-head"><div id="' + n + '-title" class="' + r + 'title">' + e.encode(i.title) + '</div><button type="button" class="' + r + 'close" aria-hidden="true">\xd7</button><div id="' + n + '-dragh" class="' + r + 'dragh"></div></div>'), i.url && (s = '<iframe src="' + i.url + '" tabindex="-1"></iframe>'), "undefined" == typeof s && (s = t.renderHtml(e)), e.statusbar && (a = e.statusbar.renderHtml()), '<div id="' + n + '" class="' + e.classes + '" hidefocus="1"><div class="' + e.classPrefix + 'reset" role="application">' + o + '<div id="' + n + '-body" class="' + e.bodyClasses + '">' + s + "</div>" + a + "</div></div>"
                    },
                    fullscreen: function(e) {
                        var t = this,
                            i = document.documentElement,
                            a, l = t.classPrefix,
                            c;
                        if (e != t._fullscreen)
                            if (r(window).on("resize", function() {
                                    var e;
                                    if (t._fullscreen)
                                        if (a) t._timer || (t._timer = s.setTimeout(function() {
                                            var e = n.getWindowSize();
                                            t.moveTo(0, 0).resizeTo(e.w, e.h), t._timer = 0
                                        }, 50));
                                        else {
                                            e = (new Date).getTime();
                                            var r = n.getWindowSize();
                                            t.moveTo(0, 0).resizeTo(r.w, r.h), (new Date).getTime() - e > 50 && (a = !0)
                                        }
                                }), c = t.layoutRect(), t._fullscreen = e, e) {
                                t._initial = {
                                    x: c.x,
                                    y: c.y,
                                    w: c.w,
                                    h: c.h
                                }, t.borderBox = o.parseBox("0"), t.getEl("head").style.display = "none", c.deltaH -= c.headerH + 2, r([i, document.body]).addClass(l + "fullscreen"), t.classes.add("fullscreen");
                                var u = n.getWindowSize();
                                t.moveTo(0, 0).resizeTo(u.w, u.h)
                            } else t.borderBox = o.parseBox(t.settings.border), t.getEl("head").style.display = "", c.deltaH += c.headerH, r([i, document.body]).removeClass(l + "fullscreen"), t.classes.remove("fullscreen"), t.moveTo(t._initial.x, t._initial.y).resizeTo(t._initial.w, t._initial.h);
                        return t.reflow()
                    },
                    postRender: function() {
                        var e = this,
                            t;
                        setTimeout(function() {
                            e.classes.add("in")
                        }, 0), e._super(), e.statusbar && e.statusbar.postRender(), e.focus(), this.dragHelper = new i(e._id + "-dragh", {
                            start: function() {
                                t = {
                                    x: e.layoutRect().x,
                                    y: e.layoutRect().y
                                }
                            },
                            drag: function(n) {
                                e.moveTo(t.x + n.deltaX, t.y + n.deltaY)
                            }
                        }), e.on("submit", function(t) {
                            t.isDefaultPrevented() || e.close()
                        }), d.push(e), l(!0)
                    },
                    submit: function() {
                        return this.fire("submit", {
                            data: this.toJSON()
                        })
                    },
                    remove: function() {
                        var e = this,
                            t;
                        for (e.dragHelper.destroy(), e._super(), e.statusbar && this.statusbar.remove(), t = d.length; t--;) d[t] === e && d.splice(t, 1);
                        l(d.length > 0), c(e.classPrefix)
                    },
                    getContentWindow: function() {
                        var e = this.getEl().getElementsByTagName("iframe")[0];
                        return e ? e.contentWindow : null
                    }
                });
            return a.desktop || u(), h
        }), r(Ne, [Ee], function(e) {
            var t = e.extend({
                init: function(e) {
                    e = {
                        border: 1,
                        padding: 20,
                        layout: "flex",
                        pack: "center",
                        align: "center",
                        containerCls: "panel",
                        autoScroll: !0,
                        buttons: {
                            type: "button",
                            text: "Ok",
                            action: "ok"
                        },
                        items: {
                            type: "label",
                            multiline: !0,
                            maxWidth: 500,
                            maxHeight: 200
                        }
                    }, this._super(e)
                },
                Statics: {
                    OK: 1,
                    OK_CANCEL: 2,
                    YES_NO: 3,
                    YES_NO_CANCEL: 4,
                    msgBox: function(n) {
                        function r(e, t, n) {
                            return {
                                type: "button",
                                text: e,
                                subtype: n ? "primary" : "",
                                onClick: function(e) {
                                    e.control.parents()[1].close(), o(t)
                                }
                            }
                        }
                        var i, o = n.callback || function() {};
                        switch (n.buttons) {
                            case t.OK_CANCEL:
                                i = [r("Ok", !0, !0), r("Cancel", !1)];
                                break;
                            case t.YES_NO:
                            case t.YES_NO_CANCEL:
                                i = [r("Yes", 1, !0), r("No", 0)], n.buttons == t.YES_NO_CANCEL && i.push(r("Cancel", -1));
                                break;
                            default:
                                i = [r("Ok", !0, !0)]
                        }
                        return new e({
                            padding: 20,
                            x: n.x,
                            y: n.y,
                            minWidth: 300,
                            minHeight: 100,
                            layout: "flex",
                            pack: "center",
                            align: "center",
                            buttons: i,
                            title: n.title,
                            role: "alertdialog",
                            items: {
                                type: "label",
                                multiline: !0,
                                maxWidth: 500,
                                maxHeight: 200,
                                text: n.text
                            },
                            onPostRender: function() {
                                this.aria("describedby", this.items()[0]._id)
                            },
                            onClose: n.onClose,
                            onCancel: function() {
                                o(!1)
                            }
                        }).renderTo(document.body).reflow()
                    },
                    alert: function(e, n) {
                        return "string" == typeof e && (e = {
                            text: e
                        }), e.callback = n, t.msgBox(e)
                    },
                    confirm: function(e, n) {
                        return "string" == typeof e && (e = {
                            text: e
                        }), e.callback = n, e.buttons = t.OK_CANCEL, t.msgBox(e)
                    }
                }
            });
            return t
        }), r(_e, [Ee, Ne], function(e, t) {
            return function(n) {
                function r() {
                    return o.length ? o[o.length - 1] : void 0
                }
                var i = this,
                    o = [];
                i.windows = o, n.on("remove", function() {
                    for (var e = o.length; e--;) o[e].close()
                }), i.open = function(t, r) {
                    var i;
                    return n.editorManager.setActive(n), t.title = t.title || " ", t.url = t.url || t.file, t.url && (t.width = parseInt(t.width || 320, 10), t.height = parseInt(t.height || 240, 10)), t.body && (t.items = {
                        defaults: t.defaults,
                        type: t.bodyType || "form",
                        items: t.body
                    }), t.url || t.buttons || (t.buttons = [{
                        text: "Ok",
                        subtype: "primary",
                        onclick: function() {
                            i.find("form")[0].submit()
                        }
                    }, {
                        text: "Cancel",
                        onclick: function() {
                            i.close()
                        }
                    }]), i = new e(t), o.push(i), i.on("close", function() {
                        for (var e = o.length; e--;) o[e] === i && o.splice(e, 1);
                        o.length || n.focus()
                    }), t.data && i.on("postRender", function() {
                        this.find("*").each(function(e) {
                            var n = e.name();
                            n in t.data && e.value(t.data[n])
                        })
                    }), i.features = t || {}, i.params = r || {}, 1 === o.length && n.nodeChanged(), i.renderTo().reflow()
                }, i.alert = function(e, r, i) {
                    t.alert(e, function() {
                        r ? r.call(i || this) : n.focus()
                    })
                }, i.confirm = function(e, n, r) {
                    t.confirm(e, function(e) {
                        n.call(r || this, e)
                    })
                }, i.close = function() {
                    r() && r().close()
                }, i.getParams = function() {
                    return r() ? r().params : null
                }, i.setParams = function(e) {
                    r() && (r().params = e)
                }, i.getWindows = function() {
                    return o
                }
            }
        }), r(Se, [he, Ce], function(e, t) {
            return e.extend({
                Mixins: [t],
                Defaults: {
                    classes: "widget tooltip tooltip-n"
                },
                renderHtml: function() {
                    var e = this,
                        t = e.classPrefix;
                    return '<div id="' + e._id + '" class="' + e.classes + '" role="presentation"><div class="' + t + 'tooltip-arrow"></div><div class="' + t + 'tooltip-inner">' + e.encode(e.state.get("text")) + "</div></div>"
                },
                bindStates: function() {
                    var e = this;
                    return e.state.on("change:text", function(t) {
                        e.getEl().lastChild.innerHTML = e.encode(t.value)
                    }), e._super()
                },
                repaint: function() {
                    var e = this,
                        t, n;
                    t = e.getEl().style, n = e._layoutRect, t.left = n.x + "px", t.top = n.y + "px", t.zIndex = 131070
                }
            })
        }), r(ke, [he, Se], function(e, t) {
            var n, r = e.extend({
                init: function(e) {
                    var t = this;
                    t._super(e), e = t.settings, t.canFocus = !0, e.tooltip && r.tooltips !== !1 && (t.on("mouseenter", function(n) {
                        var r = t.tooltip().moveTo(-65535);
                        if (n.control == t) {
                            var i = r.text(e.tooltip).show().testMoveRel(t.getEl(), ["bc-tc", "bc-tl", "bc-tr"]);
                            r.classes.toggle("tooltip-n", "bc-tc" == i), r.classes.toggle("tooltip-nw", "bc-tl" == i), r.classes.toggle("tooltip-ne", "bc-tr" == i), r.moveRel(t.getEl(), i)
                        } else r.hide()
                    }), t.on("mouseleave mousedown click", function() {
                        t.tooltip().hide()
                    })), t.aria("label", e.ariaLabel || e.tooltip)
                },
                tooltip: function() {
                    return n || (n = new t({
                        type: "tooltip"
                    }), n.renderTo()), n
                },
                postRender: function() {
                    var e = this,
                        t = e.settings;
                    e._super(), e.parent() || !t.width && !t.height || (e.initLayoutRect(), e.repaint()), t.autofocus && e.focus()
                },
                bindStates: function() {
                    function e(e) {
                        n.aria("disabled", e), n.classes.toggle("disabled", e)
                    }
    
                    function t(e) {
                        n.aria("pressed", e), n.classes.toggle("active", e)
                    }
                    var n = this;
                    return n.state.on("change:disabled", function(t) {
                        e(t.value)
                    }), n.state.on("change:active", function(e) {
                        t(e.value)
                    }), n.state.get("disabled") && e(!0), n.state.get("active") && t(!0), n._super()
                },
                remove: function() {
                    this._super(), n && (n.remove(), n = null)
                }
            });
            return r
        }), r(Te, [ke], function(e) {
            return e.extend({
                Defaults: {
                    value: 0
                },
                init: function(e) {
                    var t = this;
                    t._super(e), t.classes.add("progress"), t.settings.filter || (t.settings.filter = function(e) {
                        return Math.round(e)
                    })
                },
                renderHtml: function() {
                    var e = this,
                        t = e._id,
                        n = this.classPrefix;
                    return '<div id="' + t + '" class="' + e.classes + '"><div class="' + n + 'bar-container"><div class="' + n + 'bar"></div></div><div class="' + n + 'text">0%</div></div>'
                },
                postRender: function() {
                    var e = this;
                    return e._super(), e.value(e.settings.value), e
                },
                bindStates: function() {
                    function e(e) {
                        e = t.settings.filter(e), t.getEl().lastChild.innerHTML = e + "%", t.getEl().firstChild.firstChild.style.width = e + "%"
                    }
                    var t = this;
                    return t.state.on("change:value", function(t) {
                        e(t.value)
                    }), e(t.state.get("value")), t._super()
                }
            })
        }), r(Re, [he, Ce, Te], function(e, t, n) {
            return e.extend({
                Mixins: [t],
                Defaults: {
                    classes: "widget notification"
                },
                init: function(e) {
                    var t = this;
                    t._super(e), e.text && t.text(e.text), e.icon && (t.icon = e.icon), e.color && (t.color = e.color), e.type && t.classes.add("notification-" + e.type), e.timeout && (e.timeout < 0 || e.timeout > 0) && !e.closeButton ? t.closeButton = !1 : (t.classes.add("has-close"), t.closeButton = !0), e.progressBar && (t.progressBar = new n), t.on("click", function(e) {
                        -1 != e.target.className.indexOf(t.classPrefix + "close") && t.close()
                    })
                },
                renderHtml: function() {
                    var e = this,
                        t = e.classPrefix,
                        n = "",
                        r = "",
                        i = "",
                        o = "";
                    return e.icon && (n = '<i class="' + t + "ico " + t + "i-" + e.icon + '"></i>'), e.color && (o = ' style="background-color: ' + e.color + '"'), e.closeButton && (r = '<button type="button" class="' + t + 'close" aria-hidden="true">\xd7</button>'), e.progressBar && (i = e.progressBar.renderHtml()), '<div id="' + e._id + '" class="' + e.classes + '"' + o + ' role="presentation">' + n + '<div class="' + t + 'notification-inner">' + e.state.get("text") + "</div>" + i + r + "</div>"
                },
                bindStates: function() {
                    var e = this;
                    return e.state.on("change:text", function(t) {
                        e.getEl().childNodes[1].innerHTML = t.value
                    }), e.progressBar && e.progressBar.bindStates(), e._super()
                },
                close: function() {
                    var e = this;
                    return e.fire("close").isDefaultPrevented() || e.remove(), e
                },
                repaint: function() {
                    var e = this,
                        t, n;
                    t = e.getEl().style, n = e._layoutRect, t.left = n.x + "px", t.top = n.y + "px", t.zIndex = 131070
                }
            })
        }), r(Ae, [Re, u], function(e, t) {
            return function(n) {
                function r() {
                    return l.length ? l[l.length - 1] : void 0
                }
    
                function i() {
                    t.requestAnimationFrame(function() {
                        o(), a()
                    })
                }
    
                function o() {
                    for (var e = 0; e < l.length; e++) l[e].moveTo(0, 0)
                }
    
                function a() {
                    if (l.length > 0) {
                        var e = l.slice(0, 1)[0],
                            t = n.inline ? n.getElement() : n.getContentAreaContainer();
                        if (e.moveRel(t, "tc-tc"), l.length > 1)
                            for (var r = 1; r < l.length; r++) l[r].moveRel(l[r - 1].getEl(), "bc-tc")
                    }
                }
                var s = this,
                    l = [];
                s.notifications = l, n.on("remove", function() {
                    for (var e = l.length; e--;) l[e].close()
                }), n.on("ResizeEditor", a), n.on("ResizeWindow", i), s.open = function(t) {
                    var r;
                    return n.editorManager.setActive(n), r = new e(t), l.push(r), t.timeout > 0 && (r.timer = setTimeout(function() {
                        r.close()
                    }, t.timeout)), r.on("close", function() {
                        var e = l.length;
                        for (r.timer && n.getWin().clearTimeout(r.timer); e--;) l[e] === r && l.splice(e, 1);
                        a()
                    }), r.renderTo(), a(), r
                }, s.close = function() {
                    r() && r().close()
                }, s.getNotifications = function() {
                    return l
                }
            }
        }), r(Be, [w], function(e) {
            function t(t, n, r) {
                for (var i = []; n && n != t; n = n.parentNode) i.push(e.nodeIndex(n, r));
                return i
            }
    
            function n(e, t) {
                var n, r, i;
                for (r = e, n = t.length - 1; n >= 0; n--) {
                    if (i = r.childNodes, t[n] > i.length - 1) return null;
                    r = i[t[n]]
                }
                return r
            }
            return {
                create: t,
                resolve: n
            }
        }), r(De, [I, T, y, Be, A, C, h, m, u, k], function(e, t, n, r, i, o, a, s, l, c) {
            return function(u) {
                function d(e, t) {
                    try {
                        u.getDoc().execCommand(e, !1, t)
                    } catch (n) {}
                }
    
                function f() {
                    var e = u.getDoc().documentMode;
                    return e ? e : 6
                }
    
                function h(e) {
                    return e.isDefaultPrevented()
                }
    
                function p(e) {
                    var t, n;
                    e.dataTransfer && (u.selection.isCollapsed() && "IMG" == e.target.tagName && Q.select(e.target), t = u.selection.getContent(), t.length > 0 && (n = oe + escape(u.id) + "," + escape(t), e.dataTransfer.setData(ae, n)))
                }
    
                function m(e) {
                    var t;
                    return e.dataTransfer && (t = e.dataTransfer.getData(ae), t && t.indexOf(oe) >= 0) ? (t = t.substr(oe.length).split(","), {
                        id: unescape(t[0]),
                        html: unescape(t[1])
                    }) : null
                }
    
                function g(e) {
                    u.queryCommandSupported("mceInsertClipboardContent") ? u.execCommand("mceInsertClipboardContent", !1, {
                        content: e
                    }) : u.execCommand("mceInsertContent", !1, e)
                }
    
                function v() {
                    function i(e) {
                        var t = C.schema.getBlockElements(),
                            n = u.getBody();
                        if ("BR" != e.nodeName) return !1;
                        for (e = e; e != n && !t[e.nodeName]; e = e.parentNode)
                            if (e.nextSibling) return !1;
                        return !0
                    }
    
                    function o(e, t) {
                        var n;
                        for (n = e.nextSibling; n && n != t; n = n.nextSibling)
                            if ((3 != n.nodeType || 0 !== X.trim(n.data).length) && n !== t) return !1;
                        return n === t
                    }
    
                    function a(e, t, r) {
                        var o, a, s;
                        for (s = C.schema.getNonEmptyElements(), o = new n(r || e, e); a = o[t ? "next" : "prev"]();) {
                            if (s[a.nodeName] && !i(a)) return a;
                            if (3 == a.nodeType && a.data.length > 0) return a
                        }
                    }
    
                    function c(e) {
                        var n, r, i, o, s;
                        if (!e.collapsed && (n = C.getParent(t.getNode(e.startContainer, e.startOffset), C.isBlock), r = C.getParent(t.getNode(e.endContainer, e.endOffset), C.isBlock), s = u.schema.getTextBlockElements(), n != r && s[n.nodeName] && s[r.nodeName] && "false" !== C.getContentEditable(n) && "false" !== C.getContentEditable(r))) return e.deleteContents(), i = a(n, !1), o = a(r, !0), C.isEmpty(r) || X(n).append(r.childNodes), X(r).remove(), i ? 1 == i.nodeType ? "BR" == i.nodeName ? (e.setStartBefore(i), e.setEndBefore(i)) : (e.setStartAfter(i), e.setEndAfter(i)) : (e.setStart(i, i.data.length), e.setEnd(i, i.data.length)) : o && (1 == o.nodeType ? (e.setStartBefore(o), e.setEndBefore(o)) : (e.setStart(o, 0), e.setEnd(o, 0))), x.setRng(e), !0
                    }
    
                    function d(e, n) {
                        var r, i, s, l, c, d;
                        if (!e.collapsed) return e;
                        if (c = e.startContainer, d = e.startOffset, 3 == c.nodeType)
                            if (n) {
                                if (d < c.data.length) return e
                            } else if (d > 0) return e;
                        if (r = t.getNode(e.startContainer, e.startOffset), s = C.getParent(r, C.isBlock), i = a(u.getBody(), n, r), l = C.getParent(i, C.isBlock), !r || !i) return e;
                        if (l && s != l)
                            if (n) {
                                if (!o(s, l)) return e;
                                1 == r.nodeType ? "BR" == r.nodeName ? e.setStartBefore(r) : e.setStartAfter(r) : e.setStart(r, r.data.length), 1 == i.nodeType ? e.setEnd(i, 0) : e.setEndBefore(i)
                            } else {
                                if (!o(l, s)) return e;
                                1 == i.nodeType ? "BR" == i.nodeName ? e.setStartBefore(i) : e.setStartAfter(i) : e.setStart(i, i.data.length), 1 == r.nodeType ? e.setEnd(r, 0) : e.setEndBefore(r)
                            }
                        return e
                    }
    
                    function f(e) {
                        var t = x.getRng();
                        return t = d(t, e), c(t) ? !0 : void 0
                    }
    
                    function v(e, t) {
                        function n(e, n) {
                            return m = X(n).parents().filter(function(e, t) {
                                return !!u.schema.getTextInlineElements()[t.nodeName]
                            }), l = e.cloneNode(!1), m = s.map(m, function(e) {
                                return e = e.cloneNode(!1), l.hasChildNodes() ? (e.appendChild(l.firstChild), l.appendChild(e)) : l.appendChild(e), l.appendChild(e), e
                            }), m.length ? (p = C.create("br"), m[0].appendChild(p), C.replace(l, e), t.setStartBefore(p), t.setEndBefore(p), u.selection.setRng(t), p) : null
                        }
    
                        function i(e) {
                            return e && u.schema.getTextBlockElements()[e.tagName]
                        }
                        var o, a, l, c, d, f, h, p, m;
                        if (t.collapsed && (f = t.startContainer, h = t.startOffset, a = C.getParent(f, C.isBlock), i(a)))
                            if (1 == f.nodeType) {
                                if (f = f.childNodes[h], f && "BR" != f.tagName) return;
                                if (d = e ? a.nextSibling : a.previousSibling, C.isEmpty(a) && i(d) && C.isEmpty(d) && n(a, f)) return C.remove(d), !0
                            } else if (3 == f.nodeType) {
                            if (o = r.create(a, f), c = a.cloneNode(!0), f = r.resolve(c, o), e) {
                                if (h >= f.data.length) return;
                                f.deleteData(h, 1)
                            } else {
                                if (0 >= h) return;
                                f.deleteData(h - 1, 1)
                            }
                            if (C.isEmpty(c)) return n(a, f)
                        }
                    }
    
                    function y(e) {
                        var t, n, r;
                        f(e) || (s.each(u.getBody().getElementsByTagName("*"), function(e) {
                            "SPAN" == e.tagName && e.setAttribute("mce-data-marked", 1), !e.hasAttribute("data-mce-style") && e.hasAttribute("style") && u.dom.setAttrib(e, "style", u.dom.getAttrib(e, "style"))
                        }), t = new w(function() {}), t.observe(u.getDoc(), {
                            childList: !0,
                            attributes: !0,
                            subtree: !0,
                            attributeFilter: ["style"]
                        }), u.getDoc().execCommand(e ? "ForwardDelete" : "Delete", !1, null), n = u.selection.getRng(), r = n.startContainer.parentNode, s.each(t.takeRecords(), function(e) {
                            if (C.isChildOf(e.target, u.getBody())) {
                                if ("style" == e.attributeName) {
                                    var t = e.target.getAttribute("data-mce-style");
                                    t ? e.target.setAttribute("style", t) : e.target.removeAttribute("style")
                                }
                                s.each(e.addedNodes, function(e) {
                                    if ("SPAN" == e.nodeName && !e.getAttribute("mce-data-marked")) {
                                        var t, i;
                                        e == r && (t = n.startOffset, i = e.firstChild), C.remove(e, !0), i && (n.setStart(i, t), n.setEnd(i, t), u.selection.setRng(n))
                                    }
                                })
                            }
                        }), t.disconnect(), s.each(u.dom.select("span[mce-data-marked]"), function(e) {
                            e.removeAttribute("mce-data-marked")
                        }))
                    }
                    var b = u.getDoc(),
                        C = u.dom,
                        x = u.selection,
                        w = window.MutationObserver,
                        E, N;
                    w || (E = !0, w = function() {
                        function e(e) {
                            var t = e.relatedNode || e.target;
                            n.push({
                                target: t,
                                addedNodes: [t]
                            })
                        }
    
                        function t(e) {
                            var t = e.relatedNode || e.target;
                            n.push({
                                target: t,
                                attributeName: e.attrName
                            })
                        }
                        var n = [],
                            r;
                        this.observe = function(n) {
                            r = n, r.addEventListener("DOMSubtreeModified", e, !1), r.addEventListener("DOMNodeInsertedIntoDocument", e, !1), r.addEventListener("DOMNodeInserted", e, !1), r.addEventListener("DOMAttrModified", t, !1)
                        }, this.disconnect = function() {
                            r.removeEventListener("DOMSubtreeModified", e, !1), r.removeEventListener("DOMNodeInsertedIntoDocument", e, !1), r.removeEventListener("DOMNodeInserted", e, !1), r.removeEventListener("DOMAttrModified", t, !1)
                        }, this.takeRecords = function() {
                            return n
                        }
                    }), u.on("keydown", function(e) {
                        var t = e.keyCode == G,
                            n = e.ctrlKey || e.metaKey;
                        if (!h(e) && (t || e.keyCode == K)) {
                            var r = u.selection.getRng(),
                                i = r.startContainer,
                                o = r.startOffset;
                            if (t && e.shiftKey) return;
                            if (v(t, r)) return void e.preventDefault();
                            if (!n && r.collapsed && 3 == i.nodeType && (t ? o < i.data.length : o > 0)) return;
                            e.preventDefault(), n && u.selection.getSel().modify("extend", t ? "forward" : "backward", e.metaKey ? "lineboundary" : "word"), y(t)
                        }
                    }), u.on("keypress", function(t) {
                        if (!h(t) && !x.isCollapsed() && t.charCode > 31 && !e.metaKeyPressed(t)) {
                            var n, r, i, o, a, s;
                            n = u.selection.getRng(), s = String.fromCharCode(t.charCode), t.preventDefault(), r = X(n.startContainer).parents().filter(function(e, t) {
                                return !!u.schema.getTextInlineElements()[t.nodeName]
                            }), y(!0), r = r.filter(function(e, t) {
                                return !X.contains(u.getBody(), t)
                            }), r.length ? (i = C.createFragment(), r.each(function(e, t) {
                                t = t.cloneNode(!1), i.hasChildNodes() ? (t.appendChild(i.firstChild), i.appendChild(t)) : (a = t, i.appendChild(t)), i.appendChild(t)
                            }), a.appendChild(u.getDoc().createTextNode(s)), o = C.getParent(n.startContainer, C.isBlock), C.isEmpty(o) ? X(o).empty().append(i) : n.insertNode(i), n.setStart(a.firstChild, 1), n.setEnd(a.firstChild, 1), u.selection.setRng(n)) : u.selection.setContent(s)
                        }
                    }), u.addCommand("Delete", function() {
                        y()
                    }), u.addCommand("ForwardDelete", function() {
                        y(!0)
                    }), E || (u.on("dragstart", function(e) {
                        N = x.getRng(), p(e)
                    }), u.on("drop", function(e) {
                        if (!h(e)) {
                            var n = m(e);
                            n && (e.preventDefault(), l.setEditorTimeout(u, function() {
                                var r = t.getCaretRangeFromPoint(e.x, e.y, b);
                                N && (x.setRng(N), N = null), y(), x.setRng(r), g(n.html)
                            }))
                        }
                    }), u.on("cut", function(e) {
                        h(e) || !e.clipboardData || u.selection.isCollapsed() || (e.preventDefault(), e.clipboardData.clearData(), e.clipboardData.setData("text/html", u.selection.getContent()), e.clipboardData.setData("text/plain", u.selection.getContent({
                            format: "text"
                        })), l.setEditorTimeout(u, function() {
                            y(!0)
                        }))
                    }))
                }
    
                function y() {
                    function e(e) {
                        var t = J.create("body"),
                            n = e.cloneContents();
                        return t.appendChild(n), Q.serializer.serialize(t, {
                            format: "html"
                        })
                    }
    
                    function n(n) {
                        if (!n.setStart) {
                            if (n.item) return !1;
                            var r = n.duplicate();
                            return r.moveToElementText(u.getBody()), t.compareRanges(n, r)
                        }
                        var i = e(n),
                            o = J.createRng();
                        o.selectNode(u.getBody());
                        var a = e(o);
                        return i === a
                    }
                    u.on("keydown", function(e) {
                        var t = e.keyCode,
                            r, i;
                        if (!h(e) && (t == G || t == K)) {
                            if (r = u.selection.isCollapsed(), i = u.getBody(), r && !J.isEmpty(i)) return;
                            if (!r && !n(u.selection.getRng())) return;
                            e.preventDefault(), u.setContent(""), i.firstChild && J.isBlock(i.firstChild) ? u.selection.setCursorLocation(i.firstChild, 0) : u.selection.setCursorLocation(i, 0), u.nodeChanged()
                        }
                    })
                }
    
                function b() {
                    u.shortcuts.add("meta+a", null, "SelectAll")
                }
    
                function C() {
                    u.settings.content_editable || J.bind(u.getDoc(), "mousedown mouseup", function(e) {
                        var t;
                        if (e.target == u.getDoc().documentElement)
                            if (t = Q.getRng(), u.getBody().focus(), "mousedown" == e.type) {
                                if (c.isCaretContainer(t.startContainer)) return;
                                Q.placeCaretAt(e.clientX, e.clientY)
                            } else Q.setRng(t)
                    })
                }
    
                function x() {
                    u.on("keydown", function(e) {
                        if (!h(e) && e.keyCode === K) {
                            if (!u.getBody().getElementsByTagName("hr").length) return;
                            if (Q.isCollapsed() && 0 === Q.getRng(!0).startOffset) {
                                var t = Q.getNode(),
                                    n = t.previousSibling;
                                if ("HR" == t.nodeName) return J.remove(t), void e.preventDefault();
                                n && n.nodeName && "hr" === n.nodeName.toLowerCase() && (J.remove(n), e.preventDefault())
                            }
                        }
                    })
                }
    
                function w() {
                    window.Range.prototype.getClientRects || u.on("mousedown", function(e) {
                        if (!h(e) && "HTML" === e.target.nodeName) {
                            var t = u.getBody();
                            t.blur(), l.setEditorTimeout(u, function() {
                                t.focus()
                            })
                        }
                    })
                }
    
                function E() {
                    u.on("click", function(e) {
                        var t = e.target;
                        /^(IMG|HR)$/.test(t.nodeName) && "false" !== J.getContentEditableParent(t) && (e.preventDefault(), Q.getSel().setBaseAndExtent(t, 0, t, 1), u.nodeChanged()), "A" == t.nodeName && J.hasClass(t, "mce-item-anchor") && (e.preventDefault(), Q.select(t))
                    })
                }
    
                function N() {
                    function e() {
                        var e = J.getAttribs(Q.getStart().cloneNode(!1));
                        return function() {
                            var t = Q.getStart();
                            t !== u.getBody() && (J.setAttrib(t, "style", null), Y(e, function(e) {
                                t.setAttributeNode(e.cloneNode(!0))
                            }))
                        }
                    }
    
                    function t() {
                        return !Q.isCollapsed() && J.getParent(Q.getStart(), J.isBlock) != J.getParent(Q.getEnd(), J.isBlock)
                    }
                    u.on("keypress", function(n) {
                        var r;
                        return h(n) || 8 != n.keyCode && 46 != n.keyCode || !t() ? void 0 : (r = e(), u.getDoc().execCommand("delete", !1, null), r(), n.preventDefault(), !1)
                    }), J.bind(u.getDoc(), "cut", function(n) {
                        var r;
                        !h(n) && t() && (r = e(), l.setEditorTimeout(u, function() {
                            r()
                        }))
                    })
                }
    
                function _() {
                    document.body.setAttribute("role", "application")
                }
    
                function S() {
                    u.on("keydown", function(e) {
                        if (!h(e) && e.keyCode === K && Q.isCollapsed() && 0 === Q.getRng(!0).startOffset) {
                            var t = Q.getNode().previousSibling;
                            if (t && t.nodeName && "table" === t.nodeName.toLowerCase()) return e.preventDefault(), !1
                        }
                    })
                }
    
                function k() {
                    f() > 7 || (d("RespectVisibilityInDesign", !0), u.contentStyles.push(".mceHideBrInPre pre br {display: none}"), J.addClass(u.getBody(), "mceHideBrInPre"), ee.addNodeFilter("pre", function(e) {
                        for (var t = e.length, n, r, o, a; t--;)
                            for (n = e[t].getAll("br"), r = n.length; r--;) o = n[r], a = o.prev, a && 3 === a.type && "\n" != a.value.charAt(a.value - 1) ? a.value += "\n" : o.parent.insert(new i("#text", 3), o, !0).value = "\n"
                    }), te.addNodeFilter("pre", function(e) {
                        for (var t = e.length, n, r, i, o; t--;)
                            for (n = e[t].getAll("br"), r = n.length; r--;) i = n[r], o = i.prev, o && 3 == o.type && (o.value = o.value.replace(/\r?\n$/, ""))
                    }))
                }
    
                function T() {
                    J.bind(u.getBody(), "mouseup", function() {
                        var e, t = Q.getNode();
                        "IMG" == t.nodeName && ((e = J.getStyle(t, "width")) && (J.setAttrib(t, "width", e.replace(/[^0-9%]+/g, "")), J.setStyle(t, "width", "")), (e = J.getStyle(t, "height")) && (J.setAttrib(t, "height", e.replace(/[^0-9%]+/g, "")), J.setStyle(t, "height", "")))
                    })
                }
    
                function R() {
                    u.on("keydown", function(t) {
                        var n, r, i, o, a;
                        if (!h(t) && t.keyCode == e.BACKSPACE && (n = Q.getRng(), r = n.startContainer, i = n.startOffset, o = J.getRoot(), a = r, n.collapsed && 0 === i)) {
                            for (; a && a.parentNode && a.parentNode.firstChild == a && a.parentNode != o;) a = a.parentNode;
                            "BLOCKQUOTE" === a.tagName && (u.formatter.toggle("blockquote", null, a), n = J.createRng(), n.setStart(r, 0), n.setEnd(r, 0), Q.setRng(n))
                        }
                    })
                }
    
                function A() {
                    function e() {
                        u._refreshContentEditable(), d("StyleWithCSS", !1), d("enableInlineTableEditing", !1), Z.object_resizing || d("enableObjectResizing", !1)
                    }
                    Z.readonly || u.on("BeforeExecCommand MouseDown", e)
                }
    
                function B() {
                    function e() {
                        Y(J.select("a"), function(e) {
                            var t = e.parentNode,
                                n = J.getRoot();
                            if (t.lastChild === e) {
                                for (; t && !J.isBlock(t);) {
                                    if (t.parentNode.lastChild !== t || t === n) return;
                                    t = t.parentNode
                                }
                                J.add(t, "br", {
                                    "data-mce-bogus": 1
                                })
                            }
                        })
                    }
                    u.on("SetContent ExecCommand", function(t) {
                        ("setcontent" == t.type || "mceInsertLink" === t.command) && e()
                    })
                }
    
                function D() {
                    Z.forced_root_block && u.on("init", function() {
                        d("DefaultParagraphSeparator", Z.forced_root_block)
                    })
                }
    
                function M() {
                    u.on("keydown", function(e) {
                        var t;
                        h(e) || e.keyCode != K || (t = u.getDoc().selection.createRange(), t && t.item && (e.preventDefault(), u.undoManager.beforeChange(), J.remove(t.item(0)), u.undoManager.add()))
                    })
                }
    
                function L() {
                    var e;
                    f() >= 10 && (e = "", Y("p div h1 h2 h3 h4 h5 h6".split(" "), function(t, n) {
                        e += (n > 0 ? "," : "") + t + ":empty"
                    }), u.contentStyles.push(e + "{padding-right: 1px !important}"))
                }
    
                function P() {
                    f() < 9 && (ee.addNodeFilter("noscript", function(e) {
                        for (var t = e.length, n, r; t--;) n = e[t], r = n.firstChild, r && n.attr("data-mce-innertext", r.value)
                    }), te.addNodeFilter("noscript", function(e) {
                        for (var t = e.length, n, r, a; t--;) n = e[t], r = e[t].firstChild, r ? r.value = o.decode(r.value) : (a = n.attributes.map["data-mce-innertext"], a && (n.attr("data-mce-innertext", null), r = new i("#text", 3), r.value = a, r.raw = !0, n.append(r)))
                    }))
                }
    
                function H() {
                    function e(e, t) {
                        var n = i.createTextRange();
                        try {
                            n.moveToPoint(e, t)
                        } catch (r) {
                            n = null
                        }
                        return n
                    }
    
                    function t(t) {
                        var r;
                        t.button ? (r = e(t.x, t.y), r && (r.compareEndPoints("StartToStart", a) > 0 ? r.setEndPoint("StartToStart", a) : r.setEndPoint("EndToEnd", a), r.select())) : n()
                    }
    
                    function n() {
                        var e = r.selection.createRange();
                        a && !e.item && 0 === e.compareEndPoints("StartToEnd", e) && a.select(), J.unbind(r, "mouseup", n), J.unbind(r, "mousemove", t), a = o = 0
                    }
                    var r = J.doc,
                        i = r.body,
                        o, a, s;
                    r.documentElement.unselectable = !0, J.bind(r, "mousedown contextmenu", function(i) {
                        if ("HTML" === i.target.nodeName) {
                            if (o && n(), s = r.documentElement, s.scrollHeight > s.clientHeight) return;
                            o = 1, a = e(i.x, i.y), a && (J.bind(r, "mouseup", n), J.bind(r, "mousemove", t), J.getRoot().focus(), a.select())
                        }
                    })
                }
    
                function O() {
                    u.on("keyup focusin mouseup", function(t) {
                        65 == t.keyCode && e.metaKeyPressed(t) || Q.normalize()
                    }, !0)
                }
    
                function I() {
                    u.contentStyles.push("img:-moz-broken {-moz-force-broken-image-icon:1;min-width:24px;min-height:24px}")
                }
    
                function F() {
                    u.inline || u.on("keydown", function() {
                        document.activeElement == document.body && u.getWin().focus()
                    })
                }
    
                function z() {
                    u.inline || (u.contentStyles.push("body {min-height: 150px}"), u.on("click", function(e) {
                        var t;
                        if ("HTML" == e.target.nodeName) {
                            if (a.ie > 11) return void u.getBody().focus();
                            t = u.selection.getRng(), u.getBody().focus(), u.selection.setRng(t), u.selection.normalize(), u.nodeChanged()
                        }
                    }))
                }
    
                function W() {
                    a.mac && u.on("keydown", function(t) {
                        !e.metaKeyPressed(t) || t.shiftKey || 37 != t.keyCode && 39 != t.keyCode || (t.preventDefault(), u.selection.getSel().modify("move", 37 == t.keyCode ? "backward" : "forward", "lineboundary"))
                    })
                }
    
                function V() {
                    d("AutoUrlDetect", !1)
                }
    
                function U() {
                    u.on("click", function(e) {
                        var t = e.target;
                        do
                            if ("A" === t.tagName) return void e.preventDefault(); while (t = t.parentNode)
                    }), u.contentStyles.push(".mce-content-body {-webkit-touch-callout: none}")
                }
    
                function $() {
                    u.on("init", function() {
                        u.dom.bind(u.getBody(), "submit", function(e) {
                            e.preventDefault()
                        })
                    })
                }
    
                function q() {
                    ee.addNodeFilter("br", function(e) {
                        for (var t = e.length; t--;) "Apple-interchange-newline" == e[t].attr("class") && e[t].remove()
                    })
                }
    
                function j() {
                    u.on("dragstart", function(e) {
                        p(e)
                    }), u.on("drop", function(e) {
                        if (!h(e)) {
                            var n = m(e);
                            if (n && n.id != u.id) {
                                e.preventDefault();
                                var r = t.getCaretRangeFromPoint(e.x, e.y, u.getDoc());
                                Q.setRng(r), g(n.html)
                            }
                        }
                    })
                }
                var Y = s.each,
                    X = u.$,
                    K = e.BACKSPACE,
                    G = e.DELETE,
                    J = u.dom,
                    Q = u.selection,
                    Z = u.settings,
                    ee = u.parser,
                    te = u.serializer,
                    ne = a.gecko,
                    re = a.ie,
                    ie = a.webkit,
                    oe = "data:text/mce-internal,",
                    ae = re ? "Text" : "URL";
                R(), y(), O(), ie && (v(), C(), E(), D(), $(), S(), q(), a.iOS ? (F(), z(), U()) : b()), re && a.ie < 11 && (x(), _(), k(), T(), M(), L(), P(), H()), a.ie >= 11 && (z(), S()), a.ie && (b(), V(), j()), ne && (x(), w(), N(), A(), B(), I(), W(), S())
            }
        }), r(Me, [oe, w, m], function(e, t, n) {
            function r(e, t) {
                return "selectionchange" == t ? e.getDoc() : !e.inline && /^mouse|click|contextmenu|drop|dragover|dragend/.test(t) ? e.getDoc().documentElement : e.settings.event_root ? (e.eventRoot || (e.eventRoot = o.select(e.settings.event_root)[0]), e.eventRoot) : e.getBody()
            }
    
            function i(e, t) {
                function n(e) {
                    return !e.hidden && !e.readonly
                }
                var i = r(e, t),
                    s;
                if (e.delegates || (e.delegates = {}), !e.delegates[t])
                    if (e.settings.event_root) {
                        if (a || (a = {}, e.editorManager.on("removeEditor", function() {
                                var t;
                                if (!e.editorManager.activeEditor && a) {
                                    for (t in a) e.dom.unbind(r(e, t));
                                    a = null
                                }
                            })), a[t]) return;
                        s = function(r) {
                            for (var i = r.target, a = e.editorManager.editors, s = a.length; s--;) {
                                var l = a[s].getBody();
                                (l === i || o.isChildOf(i, l)) && n(a[s]) && a[s].fire(t, r)
                            }
                        }, a[t] = s, o.bind(i, t, s)
                    } else s = function(r) {
                        n(e) && e.fire(t, r)
                    }, o.bind(i, t, s), e.delegates[t] = s
            }
            var o = t.DOM,
                a, s = {
                    bindPendingEventDelegates: function() {
                        var e = this;
                        n.each(e._pendingNativeEvents, function(t) {
                            i(e, t)
                        })
                    },
                    toggleNativeEvent: function(e, t) {
                        var n = this;
                        "focus" != e && "blur" != e && (t ? n.initialized ? i(n, e) : n._pendingNativeEvents ? n._pendingNativeEvents.push(e) : n._pendingNativeEvents = [e] : n.initialized && (n.dom.unbind(r(n, e), e, n.delegates[e]), delete n.delegates[e]))
                    },
                    unbindAllNativeEvents: function() {
                        var e = this,
                            t;
                        if (e.delegates) {
                            for (t in e.delegates) e.dom.unbind(r(e, t), t, e.delegates[t]);
                            delete e.delegates
                        }
                        e.inline || (e.getBody().onload = null, e.dom.unbind(e.getWin()), e.dom.unbind(e.getDoc())), e.dom.unbind(e.getBody()), e.dom.unbind(e.getContainer())
                    }
                };
            return s = n.extend({}, e, s)
        }), r(Le, [], function() {
            function e(e, t, n) {
                try {
                    e.getDoc().execCommand(t, !1, n)
                } catch (r) {}
            }
    
            function t(t, n) {
                var r = t.readonly ? "readonly" : "design";
                n != r && ("readonly" == n ? (t.selection.controlSelection.hideResizeRect(), t.readonly = !0, t.getBody().contentEditable = !1) : (t.readonly = !1, t.getBody().contentEditable = !0, e(t, "StyleWithCSS", !1), e(t, "enableInlineTableEditing", !1), e(t, "enableObjectResizing", !1), t.focus(), t.nodeChanged()), t.fire("SwitchMode", {
                    mode: n
                }))
            }
            return {
                setMode: t
            }
        }), r(Pe, [m, h], function(e, t) {
            var n = e.each,
                r = e.explode,
                i = {
                    f9: 120,
                    f10: 121,
                    f11: 122
                },
                o = e.makeMap("alt,ctrl,shift,meta,access");
            return function(a) {
                function s(e, s, l, c) {
                    var u, d, f;
                    f = {
                        func: l,
                        scope: c || a,
                        desc: a.translate(s)
                    }, n(r(e, "+"), function(e) {
                        e in o ? f[e] = !0 : /^[0-9]{2,}$/.test(e) ? f.keyCode = parseInt(e, 10) : (f.charCode = e.charCodeAt(0), f.keyCode = i[e] || e.toUpperCase().charCodeAt(0))
                    }), u = [f.keyCode];
                    for (d in o) f[d] ? u.push(d) : f[d] = !1;
                    return f.id = u.join(","), f.access && (f.alt = !0, t.mac ? f.ctrl = !0 : f.shift = !0), f.meta && (t.mac ? f.meta = !0 : (f.ctrl = !0, f.meta = !1)), f
                }
                var l = this,
                    c = {};
                a.on("keyup keypress keydown", function(e) {
                    (e.altKey || e.ctrlKey || e.metaKey) && !e.isDefaultPrevented() && n(c, function(t) {
                        return t.ctrl == e.ctrlKey && t.meta == e.metaKey && t.alt == e.altKey && t.shift == e.shiftKey && (e.keyCode == t.keyCode || e.charCode && e.charCode == t.charCode) ? (e.preventDefault(), "keydown" == e.type && t.func.call(t.scope), !0) : void 0
                    })
                }), l.add = function(t, i, o, l) {
                    var u;
                    return u = o, "string" == typeof o ? o = function() {
                        a.execCommand(u, !1, null)
                    } : e.isArray(u) && (o = function() {
                        a.execCommand(u[0], u[1], u[2])
                    }), n(r(t.toLowerCase()), function(e) {
                        var t = s(e, i, o, l);
                        c[t.id] = t
                    }), !0
                }, l.remove = function(e) {
                    var t = s(e);
                    return c[t.id] ? (delete c[t.id], !0) : !1
                }
            }
        }), r(He, [c, m, z], function(e, t, n) {
            return function(r) {
                function i(e) {
                    var t, n;
                    return n = {
                        "image/jpeg": "jpg",
                        "image/jpg": "jpg",
                        "image/gif": "gif",
                        "image/png": "png"
                    }, t = n[e.blob().type.toLowerCase()] || "dat", e.id() + "." + t
                }
    
                function o(e, t) {
                    return e ? e.replace(/\/$/, "") + "/" + t.replace(/^\//, "") : t
                }
    
                function a(e) {
                    return {
                        id: e.id,
                        blob: e.blob,
                        base64: e.base64,
                        filename: n.constant(i(e))
                    }
                }
    
                function s(e, t, n, a) {
                    var s, l, c;
                    s = new XMLHttpRequest, s.open("POST", r.url), s.withCredentials = r.credentials, c = a(), s.upload.onprogress = function(e) {
                        var t = Math.round(e.loaded / e.total * 100);
                        c.progressBar.value(t)
                    }, s.onload = function() {
                        var e;
                        return c.close(), 200 != s.status ? void n("HTTP Error: " + s.status) : (e = JSON.parse(s.responseText), e && "string" == typeof e.location ? void t(o(r.basePath, e.location)) : void n("Invalid JSON: " + s.responseText))
                    }, l = new FormData, l.append("file", e.blob(), i(e)), s.send(l)
                }
    
                function l() {
                    return new e(function(e) {
                        e([])
                    })
                }
    
                function c(e) {
                    return e.then(function(e) {
                        return e
                    })["catch"](function(e) {
                        return e
                    })
                }
    
                function u(e, t, n) {
                    var r = e(n),
                        i = c(r);
                    return delete p[t], p[t] = i, i
                }
    
                function d(e, n) {
                    return t.map(e, function(e) {
                        var t = e.id();
                        return p[t] ? p[t] : u(n, t, e)
                    })
                }
    
                function f(t, n) {
                    function i(t) {
                        return new e(function(e) {
                            var i = r.handler;
                            i(a(t), function(n) {
                                e({
                                    url: n,
                                    blobInfo: t,
                                    status: !0
                                })
                            }, function(n) {
                                e({
                                    url: "",
                                    blobInfo: t,
                                    status: !1,
                                    error: n
                                })
                            }, n)
                        })
                    }
                    var o = d(t, i);
                    return e.all(o)
                }
    
                function h(e, t) {
                    return r.url || r.handler !== s ? f(e, t) : l()
                }
                var p = {};
                return r = t.extend({
                    credentials: !1,
                    handler: s
                }, r), {
                    upload: h
                }
            }
        }), r(Oe, [c], function(e) {
            function t(t) {
                return new e(function(e) {
                    var n = new XMLHttpRequest;
                    n.open("GET", t, !0), n.responseType = "blob", n.onload = function() {
                        200 == this.status && e(this.response)
                    }, n.send()
                })
            }
    
            function n(e) {
                var t, n;
                return e = decodeURIComponent(e).split(","), n = /data:([^;]+)/.exec(e[0]), n && (t = n[1]), {
                    type: t,
                    data: e[1]
                }
            }
    
            function r(t) {
                return new e(function(e) {
                    var r, i, o;
                    t = n(t);
                    try {
                        r = atob(t.data)
                    } catch (a) {
                        return void e(new Blob([]))
                    }
                    for (i = new Uint8Array(r.length), o = 0; o < i.length; o++) i[o] = r.charCodeAt(o);
                    e(new Blob([i], {
                        type: t.type
                    }))
                })
            }
    
            function i(e) {
                return 0 === e.indexOf("blob:") ? t(e) : 0 === e.indexOf("data:") ? r(e) : null
            }
    
            function o(t) {
                return new e(function(e) {
                    var n = new FileReader;
                    n.onloadend = function() {
                        e(n.result)
                    }, n.readAsDataURL(t)
                })
            }
            return {
                uriToBlob: i,
                blobToDataUri: o,
                parseDataUri: n
            }
        }), r(Ie, [c, p, z, Oe, h], function(e, t, n, r, i) {
            var o = 0;
            return function(a) {
                function s(s, c) {
                    function u(e, t) {
                        var n, i;
                        return 0 === e.src.indexOf("blob:") ? (i = a.getByUri(e.src), void(i && t({
                            image: e,
                            blobInfo: i
                        }))) : (n = r.parseDataUri(e.src).data, i = a.findFirst(function(e) {
                            return e.base64() === n
                        }), void(i ? t({
                            image: e,
                            blobInfo: i
                        }) : r.uriToBlob(e.src).then(function(r) {
                            var i = "blobid" + o++,
                                s = a.create(i, r, n);
                            a.add(s), t({
                                image: e,
                                blobInfo: s
                            })
                        })))
                    }
                    var d, f;
                    return c || (c = n.constant(!0)), d = t.filter(s.getElementsByTagName("img"), function(e) {
                        var t = e.src;
                        return i.fileApi ? e.hasAttribute("data-mce-bogus") ? !1 : e.hasAttribute("data-mce-placeholder") ? !1 : t && t != i.transparentSrc ? 0 === t.indexOf("blob:") ? !0 : 0 === t.indexOf("data:") ? c(e) : !1 : !1 : !1
                    }), f = t.map(d, function(t) {
                        var n;
                        return l[t.src] ? new e(function(e) {
                            l[t.src].then(function(n) {
                                e({
                                    image: t,
                                    blobInfo: n.blobInfo
                                })
                            })
                        }) : (n = new e(function(e) {
                            u(t, e)
                        }).then(function(e) {
                            return delete l[e.image.src], e
                        })["catch"](function(e) {
                            return delete l[t.src], e
                        }), l[t.src] = n, n)
                    }), e.all(f)
                }
                var l = {};
                return {
                    findAll: s
                }
            }
        }), r(Fe, [p, z], function(e, t) {
            return function() {
                function n(e, t, n) {
                    return {
                        id: c(e),
                        blob: c(t),
                        base64: c(n),
                        blobUri: c(URL.createObjectURL(t))
                    }
                }
    
                function r(e) {
                    i(e.id()) || l.push(e)
                }
    
                function i(e) {
                    return o(function(t) {
                        return t.id() === e
                    })
                }
    
                function o(t) {
                    return e.filter(l, t)[0]
                }
    
                function a(e) {
                    return o(function(t) {
                        return t.blobUri() == e
                    })
                }
    
                function s() {
                    e.each(l, function(e) {
                        URL.revokeObjectURL(e.blobUri())
                    }), l = []
                }
                var l = [],
                    c = t.constant;
                return {
                    create: n,
                    add: r,
                    get: i,
                    getByUri: a,
                    findFirst: o,
                    destroy: s
                }
            }
        }), r(ze, [p, He, Ie, Fe], function(e, t, n, r) {
            return function(i) {
                function o(e) {
                    return function(t) {
                        return i.selection ? e(t) : []
                    }
                }
    
                function a(e, t, n) {
                    var r = 0;
                    do r = e.indexOf(t, r), -1 !== r && (e = e.substring(0, r) + n + e.substr(r + t.length), r += n.length - t.length + 1); while (-1 !== r);
                    return e
                }
    
                function s(e, t, n) {
                    return e = a(e, 'src="' + t + '"', 'src="' + n + '"'), e = a(e, 'data-mce-src="' + t + '"', 'data-mce-src="' + n + '"')
                }
    
                function l(t, n) {
                    e.each(i.undoManager.data, function(e) {
                        e.content = s(e.content, t, n)
                    })
                }
    
                function c() {
                    return i.notificationManager.open({
                        text: i.translate("Image uploading..."),
                        type: "info",
                        timeout: -1,
                        progressBar: !0
                    })
                }
    
                function u(n) {
                    return g || (g = new t({
                        url: y.images_upload_url,
                        basePath: y.images_upload_base_path,
                        credentials: y.images_upload_credentials,
                        handler: y.images_upload_handler
                    })), f().then(o(function(t) {
                        var r;
                        return r = e.map(t, function(e) {
                            return e.blobInfo
                        }), g.upload(r, c).then(o(function(r) {
                            return r = e.map(r, function(e, n) {
                                var r = t[n].image;
                                return l(r.src, e.url), i.$(r).attr({
                                    src: e.url,
                                    "data-mce-src": i.convertURL(e.url, "src")
                                }), {
                                    element: r,
                                    status: e.status
                                }
                            }), n && n(r), r
                        }))
                    }))
                }
    
                function d(e) {
                    return y.automatic_uploads !== !1 ? u(e) : void 0
                }
    
                function f() {
                    return v || (v = new n(m)), v.findAll(i.getBody(), y.images_dataimg_filter).then(o(function(t) {
                        return e.each(t, function(e) {
                            l(e.image.src, e.blobInfo.blobUri()), e.image.src = e.blobInfo.blobUri()
                        }), t
                    }))
                }
    
                function h() {
                    m.destroy(), v = g = null
                }
    
                function p(t) {
                    return t.replace(/src="(blob:[^"]+)"/g, function(t, n) {
                        var r = m.getByUri(n);
                        return r || (r = e.reduce(i.editorManager.editors, function(e, t) {
                            return e || t.editorUpload.blobCache.getByUri(n)
                        }, null)), r ? 'src="data:' + r.blob().type + ";base64," + r.base64() + '"' : t
                    })
                }
                var m = new r,
                    g, v, y = i.settings;
                return i.on("setContent", function() {
                    i.settings.automatic_uploads !== !1 ? d() : f()
                }), i.on("RawSaveContent", function(e) {
                    e.content = p(e.content)
                }), i.on("getContent", function(e) {
                    e.source_view || "raw" == e.format || (e.content = p(e.content))
                }), {
                    blobCache: m,
                    uploadImages: u,
                    uploadImagesAuto: d,
                    scanForImages: f,
                    destroy: h
                }
            }
        }), r(We, [z, y, _, $, k, W], function(e, t, n, r, i, o) {
            function a(e) {
                return e > 0
            }
    
            function s(e) {
                return 0 > e
            }
    
            function l(e, n, r, i, o) {
                var l = new t(e, i);
                if (s(n)) {
                    if (C(e) && (e = l.prev(!0), r(e))) return e;
                    for (; e = l.prev(o);)
                        if (r(e)) return e
                }
                if (a(n)) {
                    if (C(e) && (e = l.next(!0), r(e))) return e;
                    for (; e = l.next(o);)
                        if (r(e)) return e
                }
                return null
            }
    
            function c(e, t) {
                for (e = e.parentNode; e && e != t; e = e.parentNode)
                    if (b(e)) return e;
                return t
            }
    
            function u(e, t) {
                for (; e && e != t;) {
                    if (x(e)) return e;
                    e = e.parentNode
                }
                return null
            }
    
            function d(e, t, n) {
                return u(e.container(), n) == u(t.container(), n)
            }
    
            function f(e, t, n) {
                return c(e.container(), n) == c(t.container(), n)
            }
    
            function h(e, t) {
                var n, r;
                return t ? (n = t.container(), r = t.offset(), N(n) ? n.childNodes[r + e] : null) : null
            }
    
            function p(e, t) {
                var n = t.ownerDocument.createRange();
                return e ? (n.setStartBefore(t), n.setEndBefore(t)) : (n.setStartAfter(t), n.setEndAfter(t)), n
            }
    
            function m(e, t, n) {
                return u(t, e) == u(n, e)
            }
    
            function g(e, t, n) {
                var r, i;
                for (i = e ? "previousSibling" : "nextSibling"; n && n != t;) {
                    if (r = n[i], w(r) && (r = r[i]), C(r)) {
                        if (m(t, r, n)) return r;
                        break
                    }
                    if (_(r)) break;
                    n = n.parentNode
                }
                return null
            }
    
            function v(e, t, r) {
                var o, a, s, l, c = E(g, !0, t),
                    u = E(g, !1, t);
                if (a = r.startContainer, s = r.startOffset, i.isCaretContainerBlock(a)) {
                    if (N(a) || (a = a.parentNode), l = a.getAttribute("data-mce-caret"), "before" == l && (o = a.nextSibling, C(o))) return S(o);
                    if ("after" == l && (o = a.previousSibling, C(o))) return k(o)
                }
                if (!r.collapsed) return r;
                if (n.isText(a)) {
                    if (w(a)) {
                        if (1 === e) {
                            if (o = u(a)) return S(o);
                            if (o = c(a)) return k(o)
                        }
                        if (-1 === e) {
                            if (o = c(a)) return k(o);
                            if (o = u(a)) return S(o)
                        }
                        return r
                    }
                    if (i.endsWithCaretContainer(a) && s >= a.data.length - 1) return 1 === e && (o = u(a)) ? S(o) : r;
                    if (i.startsWithCaretContainer(a) && 1 >= s) return -1 === e && (o = c(a)) ? k(o) : r;
                    if (s === a.data.length) return o = u(a), o ? S(o) : r;
                    if (0 === s) return o = c(a), o ? k(o) : r
                }
                return r
            }
    
            function y(e, t) {
                return C(h(e, t))
            }
            var b = n.isContentEditableTrue,
                C = n.isContentEditableFalse,
                x = n.matchStyleValues("display", "block table table-cell table-caption"),
                w = i.isCaretContainer,
                E = e.curry,
                N = n.isElement,
                _ = o.isCaretCandidate,
                S = E(p, !0),
                k = E(p, !1);
            return {
                isForwards: a,
                isBackwards: s,
                findNode: l,
                getEditingHost: c,
                getParentBlock: u,
                isInSameBlock: d,
                isInSameEditingHost: f,
                isBeforeContentEditableFalse: E(y, 0),
                isAfterContentEditableFalse: E(y, -1),
                normalizeRange: v
            }
        }), r(Ve, [_, W, $, We, p, z], function(e, t, n, r, i, o) {
            function a(e, t) {
                for (var n = []; e && e != t;) n.push(e), e = e.parentNode;
                return n
            }
    
            function s(e, t) {
                return e.hasChildNodes() && t < e.childNodes.length ? e.childNodes[t] : null
            }
    
            function l(e, t) {
                if (h(e)) {
                    if (m(t.previousSibling) && !d(t.previousSibling)) return n.before(t);
                    if (d(t)) return n(t, 0)
                }
                if (p(e)) {
                    if (m(t.nextSibling) && !d(t.nextSibling)) return n.after(t);
                    if (d(t)) return n(t, t.data.length)
                }
                return p(e) ? n.after(t) : n.before(t)
            }
    
            function c(e, t, c) {
                var y, b, C, x, w, E, N;
                if (!f(c) || !t) return null;
                if (N = t, y = N.container(), b = N.offset(), d(y)) {
                    if (p(e) && b > 0) return n(y, --b);
                    if (h(e) && b < y.length) return n(y, ++b);
                    C = y
                } else {
                    if (p(e) && b > 0 && (x = s(y, b - 1), m(x))) return !g(x) && (w = r.findNode(x, e, v, x)) ? d(w) ? n(w, w.data.length) : n.after(w) : d(x) ? n(x, x.data.length) : n.before(x);
                    if (h(e) && b < y.childNodes.length && (x = s(y, b), m(x))) return !g(x) && (w = r.findNode(x, e, v, x)) ? d(w) ? n(w, 0) : n.before(w) : d(x) ? n(x, 0) : n.after(x);
                    C = N.getNode()
                }
                return (h(e) && N.isAtEnd() || p(e) && N.isAtStart()) && (C = r.findNode(C, e, o.constant(!0), c, !0), v(C)) ? l(e, C) : (x = r.findNode(C, e, v, c), E = i.last(i.filter(a(y, c), u)), !E || x && E.contains(x) ? x ? l(e, x) : null : N = h(e) ? n.after(E) : n.before(E))
            }
            var u = e.isContentEditableFalse,
                d = e.isText,
                f = e.isElement,
                h = r.isForwards,
                p = r.isBackwards,
                m = t.isCaretCandidate,
                g = t.isAtomic,
                v = t.isEditableCaretCandidate;
            return function(e) {
                return {
                    next: function(t) {
                        return c(1, t, e)
                    },
                    prev: function(t) {
                        return c(-1, t, e)
                    }
                }
            }
        }), r(Ue, [k, $, _, T, g, V, u], function(e, t, n, r, i, o, a) {
            var s = n.isContentEditableFalse;
            return function(t, n) {
                function r(e, n) {
                    var r = o.collapse(e.getBoundingClientRect(), n),
                        i, a, s, l, c;
                    return "BODY" == t.tagName ? (i = t.ownerDocument.documentElement, a = t.scrollLeft || i.scrollLeft, s = t.scrollTop || i.scrollTop) : (c = t.getBoundingClientRect(), a = t.scrollLeft - c.left, s = t.scrollTop - c.top), r.left += a, r.right += a, r.top += s, r.bottom += s, r.width = 1, l = e.offsetWidth - e.clientWidth, l > 0 && (n && (l *= -1), r.left += l, r.right += l), r
                }
    
                function l() {
                    var n, r, o, a, s;
                    for (n = i("*[contentEditable=false]", t), a = 0; a < n.length; a++) r = n[a], o = r.previousSibling, e.endsWithCaretContainer(o) && (s = o.data, 1 == s.length ? o.parentNode.removeChild(o) : o.deleteData(s.length - 1, 1)), o = r.nextSibling, e.startsWithCaretContainer(o) && (s = o.data, 1 == s.length ? o.parentNode.removeChild(o) : o.deleteData(0, 1));
                    return null
                }
    
                function c(o, a) {
                    var l, c, f;
                    return u(), n(a) ? (g = e.insertBlock("p", a, o), l = r(a, o), i(g).css("top", l.top), m = i('<div class="mce-visual-caret" data-mce-bogus="all"></div>').css(l).appendTo(t), o && m.addClass("mce-visual-caret-before"), d(), c = a.ownerDocument.createRange(), f = g.firstChild, c.setStart(f, 0), c.setEnd(f, 1), c) : (g = e.insertInline(a, o), c = a.ownerDocument.createRange(), s(g.nextSibling) ? (c.setStart(g, 0), c.setEnd(g, 0)) : (c.setStart(g, 1), c.setEnd(g, 1)), c)
                }
    
                function u() {
                    l(), g && (e.remove(g), g = null), m && (m.remove(), m = null), clearInterval(p)
                }
    
                function d() {
                    p = a.setInterval(function() {
                        i("div.mce-visual-caret", t).toggleClass("mce-visual-caret-hidden")
                    }, 500)
                }
    
                function f() {
                    a.clearInterval(p)
                }
    
                function h() {
                    return ".mce-visual-caret {position: absolute;background-color: black;background-color: currentcolor;}.mce-visual-caret-hidden {display: none;}*[data-mce-caret] {position: absolute;left: -1000px;right: auto;top: 0;margin: 0;padding: 0;}"
                }
                var p, m, g;
                return {
                    show: c,
                    hide: u,
                    getCss: h,
                    destroy: f
                }
            }
        }), r($e, [p, _, V], function(e, t, n) {
            function r(i) {
                function o(t) {
                    return e.map(t, function(e) {
                        return e = n.clone(e), e.node = i, e
                    })
                }
                if (e.isArray(i)) return e.reduce(i, function(e, t) {
                    return e.concat(r(t))
                }, []);
                if (t.isElement(i)) return o(i.getClientRects());
                if (t.isText(i)) {
                    var a = i.ownerDocument.createRange();
                    return a.setStart(i, 0), a.setEnd(i, i.data.length), o(a.getClientRects())
                }
            }
            return {
                getClientRects: r
            }
        }), r(qe, [z, p, $e, W, We, Ve, $, V], function(e, t, n, r, i, o, a, s) {
            function l(e, t, n, o) {
                for (; o = i.findNode(o, e, r.isEditableCaretCandidate, t);)
                    if (n(o)) return
            }
    
            function c(e, r, i, o, a, s) {
                function c(o) {
                    var s, l, c;
                    for (c = n.getClientRects(o), -1 == e && (c = c.reverse()), s = 0; s < c.length; s++)
                        if (l = c[s], !i(l, h)) {
                            if (f.length > 0 && r(l, t.last(f)) && u++, l.line = u, a(l)) return !0;
                            f.push(l)
                        }
                }
                var u = 0,
                    d, f = [],
                    h;
                return (h = t.last(s.getClientRects())) ? (d = s.getNode(), c(d), l(e, o, c, d), f) : f
            }
    
            function u(e, t) {
                return t.line > e
            }
    
            function d(e, t) {
                return t.line === e
            }
    
            function f(e, n, r, i) {
                function l(n) {
                    return 1 == e ? t.last(n.getClientRects()) : t.last(n.getClientRects())
                }
                var c = new o(n),
                    u, d, f, h, p = [],
                    m = 0,
                    g, v;
                1 == e ? (u = c.next, d = s.isBelow, f = s.isAbove, h = a.after(i)) : (u = c.prev, d = s.isAbove, f = s.isBelow, h = a.before(i)), v = l(h);
                do
                    if (h.isVisible() && (g = l(h), !f(g, v))) {
                        if (p.length > 0 && d(g, t.last(p)) && m++, g = s.clone(g), g.position = h, g.line = m, r(g)) return p;
                        p.push(g)
                    }
                while (h = u(h));
                return p
            }
            var h = e.curry,
                p = h(c, -1, s.isAbove, s.isBelow),
                m = h(c, 1, s.isBelow, s.isAbove);
            return {
                upUntil: p,
                downUntil: m,
                positionsUntil: f,
                isAboveLine: h(u),
                isLine: h(d)
            }
        }), r(je, [z, p, _, $e, V, We, W], function(e, t, n, r, i, o, a) {
            function s(e, t) {
                return Math.abs(e.left - t)
            }
    
            function l(e, t) {
                return Math.abs(e.right - t)
            }
    
            function c(e, n) {
                function r(e, t) {
                    return e >= t.left && e <= t.right
                }
                return t.reduce(e, function(e, t) {
                    var i, o;
                    return i = Math.min(s(e, n), l(e, n)), o = Math.min(s(t, n), l(t, n)), r(n, t) ? t : r(n, e) ? e : o == i && m(t.node) ? t : i > o ? t : e
                })
            }
    
            function u(e, t, n, r) {
                for (; r = g(r, e, a.isEditableCaretCandidate, t);)
                    if (n(r)) return
            }
    
            function d(e, n) {
                function o(e, i) {
                    var o;
                    return o = t.filter(r.getClientRects(i), function(t) {
                        return !e(t, n)
                    }), a = a.concat(o), 0 === o.length
                }
                var a = [];
                return a.push(n), u(-1, e, v(o, i.isAbove), n.node), u(1, e, v(o, i.isBelow), n.node), a
            }
    
            function f(e) {
                return t.filter(t.toArray(e.getElementsByTagName("*")), m)
            }
    
            function h(e, t) {
                return {
                    node: e.node,
                    before: s(e, t) < l(e, t)
                }
            }
    
            function p(e, n, i) {
                var o, a;
                return o = r.getClientRects(f(e)), o = t.filter(o, function(e) {
                    return i >= e.top && i <= e.bottom
                }), a = c(o, n), a && (a = c(d(e, a), n), a && m(a.node)) ? h(a, n) : null
            }
            var m = n.isContentEditableFalse,
                g = o.findNode,
                v = e.curry;
            return {
                findClosestClientRect: c,
                findLineNodeRects: d,
                closestCaret: p
            }
        }), r(Ye, [_], function(e) {
            function t(e) {
                function t(e) {
                    return n(e)
                }
    
                function r(t) {
                    c(e.getBody()).css("cursor", t)
                }
    
                function i(t) {
                    return t == h.element || e.dom.isChildOf(t, h.element) ? !1 : n(t) ? !1 : !0
                }
    
                function o(t) {
                    var n, i, o, a, s = 0,
                        l = 0,
                        u, d, p, m;
                    0 === t.button && (n = t.screenX - h.screenX, i = t.screenY - h.screenY, u = Math.max(Math.abs(n), Math.abs(i)), !h.dragging && u > 10 && (h.dragging = !0, r("default"), h.clone = h.element.cloneNode(!0), o = f.getPos(h.element), h.relX = h.clientX - o.x, h.relY = h.clientY - o.y, h.width = h.element.offsetWidth, h.height = h.element.offsetHeight, c(h.clone).css({
                        width: h.width,
                        height: h.height
                    }).removeAttr("data-mce-selected"), h.ghost = c("<div>").css({
                        position: "absolute",
                        opacity: .5,
                        overflow: "hidden",
                        width: h.width,
                        height: h.height
                    }).attr({
                        "data-mce-bogus": "all",
                        unselectable: "on",
                        contenteditable: "false"
                    }).addClass("mce-drag-container mce-reset").append(h.clone).appendTo(e.getBody())[0], a = e.dom.getViewPort(e.getWin()), h.maxX = a.w, h.maxY = a.h), h.dragging && (e.selection.placeCaretAt(t.clientX, t.clientY), d = h.clientX + n - h.relX, p = h.clientY + i + 5, d + h.width > h.maxX && (s = d + h.width - h.maxX), p + h.height > h.maxY && (l = p + h.height - h.maxY), m = "BODY" != e.getBody().nodeName ? e.getBody().getBoundingClientRect() : {
                        left: 0,
                        top: 0
                    }, c(h.ghost).css({
                        left: d - m.left,
                        top: p - m.top,
                        width: h.width - s,
                        height: h.height - l
                    })))
                }
    
                function a() {
                    h.dragging && (e.selection.setRng(e.selection.getSel().getRangeAt(0)), i(e.selection.getNode()) && e.undoManager.transact(function() {
                        e.insertContent(f.getOuterHTML(h.element)), c(h.element).remove()
                    })), l()
                }
    
                function s(n) {
                    if (l(), t(n.target)) {
                        if (e.fire("dragstart", {
                                target: n.target
                            }).isDefaultPrevented()) return;
                        e.on("mousemove", o), e.on("mouseup", a), u != d && (f.bind(u, "mousemove", o), f.bind(u, "mouseup", a)), h = {
                            screenX: n.screenX,
                            screenY: n.screenY,
                            clientX: n.clientX,
                            clientY: n.clientY,
                            element: n.target
                        }
                    }
                }
    
                function l() {
                    c(h.ghost).remove(), r(null), e.off("mousemove", o), e.off("mouseup", l), u != d && (f.unbind(u, "mousemove", o), f.unbind(u, "mouseup", l)), h = {}
                }
                var c = e.$,
                    u = document,
                    d = e.getDoc(),
                    f = e.dom,
                    h = {};
                e.on("mousedown", s), e.on("drop", function(t) {
                    var r = e.getDoc().elementFromPoint(t.clientX, t.clientY);
                    (n(r) || n(e.dom.getContentEditableParent(r))) && t.preventDefault()
                })
            }
            var n = e.isContentEditableFalse;
            return {
                init: t
            }
        }), r(Xe, [h, Ve, $, k, We, Ue, qe, je, _, T, I, z, p, u, Ye], function(e, t, n, r, i, o, a, s, l, c, u, d, f, h, p) {
            function m(e, t) {
                for (; t = e(t);)
                    if (t.isVisible()) return t;
                return t
            }
    
            function g(c) {
                function d(e) {
                    return c.dom.isBlock(e)
                }
    
                function g(e) {
                    e && c.selection.setRng(e)
                }
    
                function N() {
                    return c.selection.getRng()
                }
    
                function _(e, t) {
                    c.selection.scrollIntoView(e, t)
                }
    
                function S(e, t, n) {
                    var r;
                    return r = c.fire("ShowCaret", {
                        target: t,
                        direction: e,
                        before: n
                    }), r.isDefaultPrevented() ? null : (_(t, -1 === e), Z.show(n, t))
                }
    
                function k(e) {
                    var t;
                    return t = c.fire("ObjectSelected", {
                        target: e
                    }), t.isDefaultPrevented() ? null : (Z.hide(), T(e))
                }
    
                function T(e) {
                    var t = e.ownerDocument.createRange();
                    return t.selectNode(e), t
                }
    
                function R(e, t) {
                    var n = i.isInSameBlock(e, t);
                    return !n && l.isBr(e.getNode()) ? !0 : n
                }
    
                function A(e, t) {
                    return t = i.normalizeRange(e, K, t), -1 == e ? n.fromRangeStart(t) : n.fromRangeEnd(t)
                }
    
                function B(e) {
                    return r.isCaretContainerBlock(e.startContainer)
                }
    
                function D(e, t, n, r) {
                    var i, o, a, s;
                    return !r.collapsed && (i = E(r), b(i)) ? S(e, i, -1 == e) : (s = B(r), o = A(e, r), n(o) ? k(o.getNode(-1 == e)) : (o = t(o)) ? n(o) ? S(e, o.getNode(-1 == e), 1 == e) : (a = t(o), n(a) && R(o, a) ? S(e, a.getNode(-1 == e), 1 == e) : s ? z(o.toRange()) : null) : s ? r : null)
                }
    
                function M(e, t, n) {
                    var r, i, o, l, c, u, d, h, p;
                    if (p = E(n), r = A(e, n), i = t(K, a.isAboveLine(1), r), o = f.filter(i, a.isLine(1)), c = f.last(r.getClientRects()), w(r) && (p = r.getNode()), x(r) && (p = r.getNode(!0)), !c) return null;
                    if (u = c.left, l = s.findClosestClientRect(o, u), l && b(l.node)) return d = Math.abs(u - l.left), h = Math.abs(u - l.right), S(e, l.node, h > d);
                    if (p) {
                        var m = a.positionsUntil(e, K, a.isAboveLine(1), p);
                        if (l = s.findClosestClientRect(f.filter(m, a.isLine(1)), u)) return z(l.position.toRange());
                        if (l = f.last(f.filter(m, a.isLine(0)))) return z(l.position.toRange())
                    }
                }
    
                function L(t, r) {
                    function i() {
                        var t = c.dom.create(c.settings.forced_root_block);
                        return (!e.ie || e.ie >= 11) && (t.innerHTML = '<br data-mce-bogus="1">'), t
                    }
                    var o, a, s;
                    if (r.collapsed && c.settings.forced_root_block) {
                        if (o = c.dom.getParent(r.startContainer, "PRE"), !o) return;
                        a = 1 == t ? J(n.fromRangeStart(r)) : Q(n.fromRangeStart(r)), a || (s = i(), 1 == t ? c.$(o).after(s) : c.$(o).before(s), c.selection.select(s, !0), c.selection.collapse())
                    }
                }
    
                function P(e, t, n, r) {
                    var i;
                    return (i = D(e, t, n, r)) ? i : (i = L(e, r), i ? i : null)
                }
    
                function H(e, t, n) {
                    var r;
                    return (r = M(e, t, n)) ? r : (r = L(e, n), r ? r : null)
                }
    
                function O() {
                    return ne("*[data-mce-caret]")[0]
                }
    
                function I(e) {
                    e = ne(e), e.attr("data-mce-caret") && (Z.hide(), e.removeAttr("data-mce-caret"), e.removeAttr("data-mce-bogus"), e.removeAttr("style"), g(N()), _(e[0]))
                }
    
                function F(e) {
                    var t;
                    return e = i.normalizeRange(1, K, e), t = n.fromRangeStart(e), b(t.getNode()) ? S(1, t.getNode(), !t.isAtEnd()) : b(t.getNode(!0)) ? S(1, t.getNode(!0), !1) : (Z.hide(), null)
                }
    
                function z(e) {
                    var t;
                    return e && e.collapsed ? (t = F(e), t ? t : e) : e
                }
    
                function W(e) {
                    var t, i, o, a;
                    return b(e) ? (b(e.previousSibling) && (o = e.previousSibling), i = Q(n.before(e)), i || (t = J(n.after(e))), t && C(t.getNode()) && (a = t.getNode()), r.remove(e.previousSibling), r.remove(e.nextSibling), c.dom.remove(e), Y(), c.dom.isEmpty(c.getBody()) ? (c.setContent(""), void c.focus()) : o ? n.after(o).toRange() : a ? n.before(a).toRange() : i ? i.toRange() : t ? t.toRange() : null) : null
                }
    
                function V(e, t, n) {
                    var r, i;
                    return !n.collapsed && (r = E(n), b(r)) ? z(W(r)) : (i = A(e, n), t(i) ? z(W(i.getNode(-1 == e))) : void 0)
                }
    
                function U() {
                    function e(e) {
                        var t = e(N());
                        return t ? (g(t), !0) : !1
                    }
    
                    function t(e) {
                        for (var t = c.getBody(); e && e != t;) {
                            if (y(e) || b(e)) return e;
                            e = e.parentNode
                        }
                        return null
                    }
    
                    function r() {
                        var e, r = t(c.selection.getNode());
                        y(r) && d(r) && c.dom.isEmpty(r) && (e = c.dom.create("br", {
                            "data-mce-bogus": "1"
                        }), c.$(r).empty().append(e), c.selection.setRng(n.before(e).toRange()))
                    }
    
                    function i(e) {
                        var t = O();
                        if (t) return "compositionstart" == e.type ? (e.preventDefault(), e.stopPropagation(), void I(t)) : void("&nbsp;" != t.innerHTML && I(t))
                    }
    
                    function o(e) {
                        var t;
                        switch (e.keyCode) {
                            case u.DELETE:
                                t = r();
                                break;
                            case u.BACKSPACE:
                                t = r()
                        }
                        t && e.preventDefault()
                    }
                    var l = v(P, 1, J, w),
                        f = v(P, -1, Q, x),
                        m = v(V, 1, w),
                        C = v(V, -1, x),
                        E = v(H, -1, a.upUntil),
                        _ = v(H, 1, a.downUntil);
                    c.on("mouseup", function() {
                        var e = N();
                        e.collapsed && g(F(e))
                    }), c.on("mousedown", function(e) {
                        var n;
                        if (n = t(e.target)) b(n) ? (e.preventDefault(), j(k(n), !1)) : c.selection.placeCaretAt(e.clientX, e.clientY);
                        else {
                            Y(), Z.hide();
                            var r = s.closestCaret(K, e.clientX, e.clientY);
                            r && (e.preventDefault(), c.getBody().focus(), g(S(1, r.node, r.before)))
                        }
                    }), c.on("keydown", function(t) {
                        var n;
                        if (!u.modifierPressed(t)) {
                            switch (t.keyCode) {
                                case u.RIGHT:
                                    n = e(l);
                                    break;
                                case u.DOWN:
                                    n = e(_);
                                    break;
                                case u.LEFT:
                                    n = e(f);
                                    break;
                                case u.UP:
                                    n = e(E);
                                    break;
                                case u.DELETE:
                                    n = e(m);
                                    break;
                                case u.BACKSPACE:
                                    n = e(C);
                                    break;
                                default:
                                    n = b(c.selection.getNode())
                            }
                            n && t.preventDefault()
                        }
                    }), c.on("keyup compositionstart", function(e) {
                        i(e), o(e)
                    }, !0), c.on("cut", function() {
                        var e = c.selection.getNode();
                        b(e) && h.setEditorTimeout(c, function() {
                            g(z(W(e)))
                        })
                    }), c.on("getSelectionRange", function(e) {
                        var t = e.range;
                        if (te) {
                            if (!te.parentNode) return void(te = null);
                            t = t.cloneRange(), t.selectNode(te), e.range = t
                        }
                    }), c.on("setSelectionRange", function(e) {
                        var t;
                        t = j(e.range), t && (e.range = t)
                    }), c.on("focus", function() {
                        h.setEditorTimeout(c, function() {
                            c.selection.setRng(z(c.selection.getRng()))
                        })
                    }), p.init(c)
                }
    
                function $() {
                    var e = c.contentStyles,
                        t = ".mce-content-body";
                    e.push(Z.getCss()), e.push(t + " .mce-offscreen-selection {position: absolute;left: -9999999999px;width: 100pxheight: 100px}" + t + " *[contentEditable=false] {cursor: default;}" + t + " *[contentEditable=true] {cursor: text;}")
                }
    
                function q(e) {
                    return r.isCaretContainer(e.startContainer) || r.isCaretContainer(e.endContainer)
                }
    
                function j(e, t) {
                    var n, r = c.$,
                        i = c.dom,
                        o, a, s, l, u, d, f;
                    if (!e) return Y(), null;
                    if (e.collapsed) {
                        if (Y(), !q(e)) {
                            if (f = A(1, e), b(f.getNode())) return S(1, f.getNode(), !f.isAtEnd());
                            if (b(f.getNode(!0))) return S(1, f.getNode(!0), !1)
                        }
                        return null
                    }
                    return s = e.startContainer, l = e.startOffset, u = e.endOffset, 3 == s.nodeType && 0 == l && b(s.parentNode) && (s = s.parentNode, l = i.nodeIndex(s), s = s.parentNode), 1 != s.nodeType ? (Y(), null) : (u == l + 1 && (n = s.childNodes[l]), b(n) ? t !== !1 && (d = c.fire("ObjectSelected", {
                        target: n
                    }), d.isDefaultPrevented()) ? (Y(), null) : (o = r("#" + ee), 0 === o.length && (o = r('<div data-mce-bogus="all" class="mce-offscreen-selection"></div>').attr("id", ee), o.appendTo(c.getBody())), o.empty().append("\xa0").append(n.cloneNode(!0)).append("\xa0").css({
                        top: i.getPos(n, c.getBody()).y
                    }), e = c.dom.createRng(), e.setStart(o[0].firstChild, 1), e.setEnd(o[0].lastChild, 0), c.getBody().focus(), o[0].focus(), a = c.selection.getSel(), a.removeAllRanges(), a.addRange(e), c.$("*[data-mce-selected]").removeAttr("data-mce-selected"), n.setAttribute("data-mce-selected", 1), te = n, e) : (Y(), null))
                }
    
                function Y() {
                    te && (te.removeAttribute("data-mce-selected"), c.$("#" + ee).remove(), te = null)
                }
    
                function X() {
                    Z.destroy(), te = null
                }
                var K = c.getBody(),
                    G = new t(K),
                    J = v(m, G.next),
                    Q = v(m, G.prev),
                    Z = new o(c.getBody(), d),
                    ee = "sel-" + c.dom.uniqueId(),
                    te, ne = c.$;
                return e.ceFalse && (U(), $()), {
                    showBlockCaretContainer: I,
                    destroy: X
                }
            }
            var v = d.curry,
                y = l.isContentEditableTrue,
                b = l.isContentEditableFalse,
                C = l.isElement,
                x = i.isAfterContentEditableFalse,
                w = i.isBeforeContentEditableFalse,
                E = c.getSelectedNode;
            return g
        }), r(Ke, [w, g, N, R, A, H, P, Y, G, J, Q, Z, ee, te, E, d, _e, Ae, B, M, De, h, m, u, Me, Le, Pe, ze, Xe], function(e, n, r, i, o, a, s, l, c, u, d, f, h, p, m, g, v, y, b, C, x, w, E, N, _, S, k, T, R) {
            function A(e, t, i) {
                var o = this,
                    a, s;
                a = o.documentBaseUrl = i.documentBaseURL, s = i.baseURI, o.settings = t = L({
                    id: e,
                    theme: "modern",
                    delta_width: 0,
                    delta_height: 0,
                    popup_css: "",
                    plugins: "",
                    document_base_url: a,
                    add_form_submit_trigger: !0,
                    submit_patch: !0,
                    add_unload_trigger: !0,
                    convert_urls: !0,
                    relative_urls: !0,
                    remove_script_host: !0,
                    object_resizing: !0,
                    doctype: "<!DOCTYPE html>",
                    visual: !0,
                    font_size_style_values: "xx-small,x-small,small,medium,large,x-large,xx-large",
                    font_size_legacy_values: "xx-small,small,medium,large,x-large,xx-large,300%",
                    forced_root_block: "p",
                    hidden_input: !0,
                    padd_empty_editor: !0,
                    render_ui: !0,
                    indentation: "30px",
                    inline_styles: !0,
                    convert_fonts_to_spans: !0,
                    indent: "simple",
                    indent_before: "p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure,figcaption,option,optgroup,datalist",
                    indent_after: "p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure,figcaption,option,optgroup,datalist",
                    validate: !0,
                    entity_encoding: "named",
                    url_converter: o.convertURL,
                    url_converter_scope: o,
                    ie7_compat: !0
                }, t), r.language = t.language || "en", r.languageLoad = t.language_load, r.baseURL = i.baseURL, o.id = t.id = e, o.setDirty(!1), o.plugins = {}, o.documentBaseURI = new p(t.document_base_url || a, {
                    base_uri: s
                }), o.baseURI = s, o.contentCSS = [], o.contentStyles = [], o.shortcuts = new k(o), o.loadedCSS = {}, o.editorCommands = new h(o), t.target && (o.targetElm = t.target), o.suffix = i.suffix, o.editorManager = i, o.inline = t.inline, t.cache_suffix && (w.cacheSuffix = t.cache_suffix.replace(/^[\?\&]+/, "")), t.override_viewport === !1 && (w.overrideViewPort = !1), i.fire("SetupEditor", o), o.execCallback("setup", o), o.$ = n.overrideDefaults(function() {
                    return {
                        context: o.inline ? o.getBody() : o.getDoc(),
                        element: o.getBody()
                    }
                })
            }
            var B = e.DOM,
                D = r.ThemeManager,
                M = r.PluginManager,
                L = E.extend,
                P = E.each,
                H = E.explode,
                O = E.inArray,
                I = E.trim,
                F = E.resolve,
                z = g.Event,
                W = w.gecko,
                V = w.ie;
            return A.prototype = {
                render: function() {
                    function e() {
                        B.unbind(window, "ready", e), n.render()
                    }
    
                    function t() {
                        var e = m.ScriptLoader;
                        if (r.language && "en" != r.language && !r.language_url && (r.language_url = n.editorManager.baseURL + "/langs/" + r.language + ".js"), r.language_url && e.add(r.language_url), r.theme && "function" != typeof r.theme && "-" != r.theme.charAt(0) && !D.urls[r.theme]) {
                            var t = r.theme_url;
                            t = t ? n.documentBaseURI.toAbsolute(t) : "themes/" + r.theme + "/theme" + o + ".js", D.load(r.theme, t)
                        }
                        E.isArray(r.plugins) && (r.plugins = r.plugins.join(" ")), P(r.external_plugins, function(e, t) {
                            M.load(t, e), r.plugins += " " + t
                        }), P(r.plugins.split(/[ ,]/), function(e) {
                            if (e = I(e), e && !M.urls[e])
                                if ("-" == e.charAt(0)) {
                                    e = e.substr(1, e.length);
                                    var t = M.dependencies(e);
                                    P(t, function(e) {
                                        var t = {
                                            prefix: "plugins/",
                                            resource: e,
                                            suffix: "/plugin" + o + ".js"
                                        };
                                        e = M.createUrl(t, e), M.load(e.resource, e)
                                    })
                                } else M.load(e, {
                                    prefix: "plugins/",
                                    resource: e,
                                    suffix: "/plugin" + o + ".js"
                                })
                        }), e.loadQueue(function() {
                            n.removed || n.init()
                        })
                    }
                    var n = this,
                        r = n.settings,
                        i = n.id,
                        o = n.suffix;
                    if (!z.domLoaded) return void B.bind(window, "ready", e);
                    if (n.getElement() && w.contentEditable) {
                        r.inline ? n.inline = !0 : (n.orgVisibility = n.getElement().style.visibility, n.getElement().style.visibility = "hidden");
                        var a = n.getElement().form || B.getParent(i, "form");
                        a && (n.formElement = a, r.hidden_input && !/TEXTAREA|INPUT/i.test(n.getElement().nodeName) && (B.insertAfter(B.create("input", {
                            type: "hidden",
                            name: i
                        }), i), n.hasHiddenInput = !0), n.formEventDelegate = function(e) {
                            n.fire(e.type, e)
                        }, B.bind(a, "submit reset", n.formEventDelegate), n.on("reset", function() {
                            n.setContent(n.startContent, {
                                format: "raw"
                            })
                        }), !r.submit_patch || a.submit.nodeType || a.submit.length || a._mceOldSubmit || (a._mceOldSubmit = a.submit, a.submit = function() {
                            return n.editorManager.triggerSave(), n.setDirty(!1), a._mceOldSubmit(a)
                        })), n.windowManager = new v(n), n.notificationManager = new y(n), "xml" == r.encoding && n.on("GetContent", function(e) {
                            e.save && (e.content = B.encode(e.content))
                        }), r.add_form_submit_trigger && n.on("submit", function() {
                            n.initialized && n.save()
                        }), r.add_unload_trigger && (n._beforeUnload = function() {
                            !n.initialized || n.destroyed || n.isHidden() || n.save({
                                format: "raw",
                                no_events: !0,
                                set_dirty: !1
                            })
                        }, n.editorManager.on("BeforeUnload", n._beforeUnload)), t()
                    }
                },
                init: function() {
                    function e(n) {
                        var r = M.get(n),
                            i, o;
                        if (i = M.urls[n] || t.documentBaseUrl.replace(/\/$/, ""), n = I(n), r && -1 === O(m, n)) {
                            if (P(M.dependencies(n), function(t) {
                                    e(t)
                                }), t.plugins[n]) return;
                            o = new r(t, i, t.$), t.plugins[n] = o, o.init && (o.init(t, i), m.push(n))
                        }
                    }
                    var t = this,
                        n = t.settings,
                        r = t.getElement(),
                        i, o, a, s, l, c, u, d, f, h, p, m = [];
                    if (this.editorManager.i18n.setCode(n.language), t.rtl = n.rtl_ui || this.editorManager.i18n.rtl, t.editorManager.add(t), n.aria_label = n.aria_label || B.getAttrib(r, "aria-label", t.getLang("aria.rich_text_area")), n.theme && ("function" != typeof n.theme ? (n.theme = n.theme.replace(/-/, ""), c = D.get(n.theme), t.theme = new c(t, D.urls[n.theme]), t.theme.init && t.theme.init(t, D.urls[n.theme] || t.documentBaseUrl.replace(/\/$/, ""), t.$)) : t.theme = n.theme), P(n.plugins.replace(/\-/g, "").split(/[ ,]/), e), n.render_ui && t.theme && (t.orgDisplay = r.style.display, "function" != typeof n.theme ? (i = n.width || r.style.width || r.offsetWidth, o = n.height || r.style.height || r.offsetHeight, a = n.min_height || 100, h = /^[0-9\.]+(|px)$/i, h.test("" + i) && (i = Math.max(parseInt(i, 10), 100)), h.test("" + o) && (o = Math.max(parseInt(o, 10), a)), l = t.theme.renderUI({
                            targetNode: r,
                            width: i,
                            height: o,
                            deltaWidth: n.delta_width,
                            deltaHeight: n.delta_height
                        }), n.content_editable || (o = (l.iframeHeight || o) + ("number" == typeof o ? l.deltaHeight || 0 : ""), a > o && (o = a))) : (l = n.theme(t, r), l.editorContainer.nodeType && (l.editorContainer = l.editorContainer.id = l.editorContainer.id || t.id + "_parent"), l.iframeContainer.nodeType && (l.iframeContainer = l.iframeContainer.id = l.iframeContainer.id || t.id + "_iframecontainer"), o = l.iframeHeight || r.offsetHeight), t.editorContainer = l.editorContainer), n.content_css && P(H(n.content_css), function(e) {
                            t.contentCSS.push(t.documentBaseURI.toAbsolute(e))
                        }), n.content_style && t.contentStyles.push(n.content_style), n.content_editable) return r = s = l = null, t.initContentBody();
                    for (t.iframeHTML = n.doctype + "<html><head>", n.document_base_url != t.documentBaseUrl && (t.iframeHTML += '<base href="' + t.documentBaseURI.getURI() + '" />'), !w.caretAfter && n.ie7_compat && (t.iframeHTML += '<meta http-equiv="X-UA-Compatible" content="IE=7" />'), t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />', p = 0; p < t.contentCSS.length; p++) {
                        var g = t.contentCSS[p];
                        t.iframeHTML += '<link type="text/css" rel="stylesheet" href="' + E._addCacheSuffix(g) + '" />', t.loadedCSS[g] = !0
                    }
                    d = n.body_id || "tinymce", -1 != d.indexOf("=") && (d = t.getParam("body_id", "", "hash"), d = d[t.id] || d), f = n.body_class || "", -1 != f.indexOf("=") && (f = t.getParam("body_class", "", "hash"), f = f[t.id] || ""), n.content_security_policy && (t.iframeHTML += '<meta http-equiv="Content-Security-Policy" content="' + n.content_security_policy + '" />'), t.iframeHTML += '</head><body id="' + d + '" class="mce-content-body ' + f + '" data-id="' + t.id + '"><br></body></html>';
                    var v = 'javascript:(function(){document.open();document.domain="' + document.domain + '";var ed = window.parent.tinymce.get("' + t.id + '");document.write(ed.iframeHTML);document.close();ed.initContentBody(true);})()';
                    document.domain != location.hostname && w.ie && w.ie < 12 && (u = v);
                    var y = B.create("iframe", {
                        id: t.id + "_ifr",
                        frameBorder: "0",
                        allowTransparency: "true",
                        title: t.editorManager.translate("Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help"),
                        style: {
                            width: "100%",
                            height: o,
                            display: "block"
                        }
                    });
                    if (y.onload = function() {
                            y.onload = null, t.fire("load")
                        }, B.setAttrib(y, "src", u || 'javascript:""'), t.contentAreaContainer = l.iframeContainer, t.iframeElement = y, s = B.add(l.iframeContainer, y), V) try {
                        t.getDoc()
                    } catch (b) {
                        s.src = u = v
                    }
                    l.editorContainer && (B.get(l.editorContainer).style.display = t.orgDisplay, t.hidden = B.isHidden(l.editorContainer)), t.getElement().style.display = "none", B.setAttrib(t.id, "aria-hidden", !0), u || t.initContentBody(), r = s = l = null
                },
                initContentBody: function(t) {
                    var n = this,
                        r = n.settings,
                        s = n.getElement(),
                        h = n.getDoc(),
                        p, m;
                    r.inline || (n.getElement().style.visibility = n.orgVisibility), t || r.content_editable || (h.open(), h.write(n.iframeHTML), h.close()), r.content_editable && (n.on("remove", function() {
                        var e = this.getBody();
                        B.removeClass(e, "mce-content-body"), B.removeClass(e, "mce-edit-focus"), B.setAttrib(e, "contentEditable", null)
                    }), B.addClass(s, "mce-content-body"), n.contentDocument = h = r.content_document || document, n.contentWindow = r.content_window || window, n.bodyElement = s, r.content_document = r.content_window = null, r.root_name = s.nodeName.toLowerCase()), p = n.getBody(), p.disabled = !0, n.readonly = r.readonly, n.readonly || (n.inline && "static" == B.getStyle(p, "position", !0) && (p.style.position = "relative"), p.contentEditable = n.getParam("content_editable_state", !0)), p.disabled = !1, n.editorUpload = new T(n), n.schema = new b(r), n.dom = new e(h, {
                        keep_values: !0,
                        url_converter: n.convertURL,
                        url_converter_scope: n,
                        hex_colors: r.force_hex_style_colors,
                        class_filter: r.class_filter,
                        update_styles: !0,
                        root_element: n.inline ? n.getBody() : null,
                        collect: r.content_editable,
                        schema: n.schema,
                        onSetAttrib: function(e) {
                            n.fire("SetAttrib", e)
                        }
                    }), n.parser = new C(r, n.schema), n.parser.addAttributeFilter("src,href,style,tabindex", function(e, t) {
                        for (var r = e.length, i, o = n.dom, a, s; r--;)
                            if (i = e[r], a = i.attr(t), s = "data-mce-" + t, !i.attributes.map[s]) {
                                if (0 === a.indexOf("data:") || 0 === a.indexOf("blob:")) continue;
                                "style" === t ? (a = o.serializeStyle(o.parseStyle(a), i.name), a.length || (a = null), i.attr(s, a), i.attr(t, a)) : "tabindex" === t ? (i.attr(s, a), i.attr(t, null)) : i.attr(s, n.convertURL(a, t, i.name))
                            }
                    }), n.parser.addNodeFilter("script", function(e) {
                        for (var t = e.length, n, r; t--;) n = e[t], r = n.attr("type") || "no/type", 0 !== r.indexOf("mce-") && n.attr("type", "mce-" + r)
                    }), n.parser.addNodeFilter("#cdata", function(e) {
                        for (var t = e.length, n; t--;) n = e[t], n.type = 8, n.name = "#comment", n.value = "[CDATA[" + n.value + "]]"
                    }), n.parser.addNodeFilter("p,h1,h2,h3,h4,h5,h6,div", function(e) {
                        for (var t = e.length, r, i = n.schema.getNonEmptyElements(); t--;) r = e[t], r.isEmpty(i) && (r.append(new o("br", 1)).shortEnded = !0)
                    }), n.serializer = new a(r, n), n.selection = new l(n.dom, n.getWin(), n.serializer, n), n.formatter = new c(n), n.undoManager = new u(n), n.forceBlocks = new f(n), n.enterKey = new d(n), n._nodeChangeDispatcher = new i(n), n._selectionOverrides = new R(n), n.fire("PreInit"), r.browser_spellcheck || r.gecko_spellcheck || (h.body.spellcheck = !1, B.setAttrib(p, "spellcheck", "false")), n.fire("PostRender"), n.quirks = new x(n), r.directionality && (p.dir = r.directionality), r.nowrap && (p.style.whiteSpace = "nowrap"), r.protect && n.on("BeforeSetContent", function(e) {
                        P(r.protect, function(t) {
                            e.content = e.content.replace(t, function(e) {
                                return "<!--mce:protected " + escape(e) + "-->"
                            })
                        })
                    }), n.on("SetContent", function() {
                        n.addVisual(n.getBody())
                    }), r.padd_empty_editor && n.on("PostProcess", function(e) {
                        e.content = e.content.replace(/^(<p[^>]*>(&nbsp;|&#160;|\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/, "")
                    }), n.load({
                        initial: !0,
                        format: "html"
                    }), n.startContent = n.getContent({
                        format: "raw"
                    }), n.initialized = !0, n.bindPendingEventDelegates(), n.fire("init"), n.focus(!0), n.nodeChanged({
                        initial: !0
                    }), n.execCallback("init_instance_callback", n), n.contentStyles.length > 0 && (m = "", P(n.contentStyles, function(e) {
                        m += e + "\r\n"
                    }), n.dom.addStyle(m)), P(n.contentCSS, function(e) {
                        n.loadedCSS[e] || (n.dom.loadCSS(e), n.loadedCSS[e] = !0)
                    }), r.auto_focus && N.setEditorTimeout(n, function() {
                        var e;
                        e = r.auto_focus === !0 ? n : n.editorManager.get(r.auto_focus), e.destroyed || e.focus()
                    }, 100), s = h = p = null
                },
                focus: function(e) {
                    function t(e) {
                        return n.dom.getParent(e, function(e) {
                            return "true" === n.dom.getContentEditable(e)
                        })
                    }
                    var n = this,
                        r = n.selection,
                        i = n.settings.content_editable,
                        o, a, s = n.getDoc(),
                        l = n.getBody(),
                        c;
                    if (!e) {
                        if (o = r.getRng(), o.item && (a = o.item(0)), n._refreshContentEditable(), c = t(r.getNode()), n.$.contains(l, c)) return c.focus(), r.normalize(), void n.editorManager.setActive(n);
                        if (i || (w.opera || n.getBody().focus(), n.getWin().focus()), W || i) {
                            if (l.setActive) try {
                                l.setActive()
                            } catch (u) {
                                l.focus()
                            } else l.focus();
                            i && r.normalize()
                        }
                        a && a.ownerDocument == s && (o = s.body.createControlRange(), o.addElement(a), o.select())
                    }
                    n.editorManager.setActive(n)
                },
                execCallback: function(e) {
                    var t = this,
                        n = t.settings[e],
                        r;
                    if (n) return t.callbackLookup && (r = t.callbackLookup[e]) && (n = r.func, r = r.scope), "string" == typeof n && (r = n.replace(/\.\w+$/, ""), r = r ? F(r) : 0, n = F(n), t.callbackLookup = t.callbackLookup || {}, t.callbackLookup[e] = {
                        func: n,
                        scope: r
                    }), n.apply(r || t, Array.prototype.slice.call(arguments, 1))
                },
                translate: function(e) {
                    var t = this.settings.language || "en",
                        n = this.editorManager.i18n;
                    return e ? n.data[t + "." + e] || e.replace(/\{\#([^\}]+)\}/g, function(e, r) {
                        return n.data[t + "." + r] || "{#" + r + "}"
                    }) : ""
                },
                getLang: function(e, n) {
                    return this.editorManager.i18n.data[(this.settings.language || "en") + "." + e] || (n !== t ? n : "{#" + e + "}")
                },
                getParam: function(e, t, n) {
                    var r = e in this.settings ? this.settings[e] : t,
                        i;
                    return "hash" === n ? (i = {}, "string" == typeof r ? P(r.indexOf("=") > 0 ? r.split(/[;,](?![^=;,]*(?:[;,]|$))/) : r.split(","), function(e) {
                        e = e.split("="), e.length > 1 ? i[I(e[0])] = I(e[1]) : i[I(e[0])] = I(e)
                    }) : i = r, i) : r
                },
                nodeChanged: function(e) {
                    this._nodeChangeDispatcher.nodeChanged(e)
                },
                addButton: function(e, t) {
                    var n = this;
                    t.cmd && (t.onclick = function() {
                        n.execCommand(t.cmd)
                    }), t.text || t.icon || (t.icon = e), n.buttons = n.buttons || {}, t.tooltip = t.tooltip || t.title, n.buttons[e] = t
                },
                addMenuItem: function(e, t) {
                    var n = this;
                    t.cmd && (t.onclick = function() {
                        n.execCommand(t.cmd)
                    }), n.menuItems = n.menuItems || {}, n.menuItems[e] = t
                },
                addContextToolbar: function(e, t) {
                    var n = this,
                        r;
                    n.contextToolbars = n.contextToolbars || [], "string" == typeof e && (r = e, e = function(e) {
                        return n.dom.is(e, r)
                    }), n.contextToolbars.push({
                        predicate: e,
                        items: t
                    })
                },
                addCommand: function(e, t, n) {
                    this.editorCommands.addCommand(e, t, n)
                },
                addQueryStateHandler: function(e, t, n) {
                    this.editorCommands.addQueryStateHandler(e, t, n)
                },
                addQueryValueHandler: function(e, t, n) {
                    this.editorCommands.addQueryValueHandler(e, t, n)
                },
                addShortcut: function(e, t, n, r) {
                    this.shortcuts.add(e, t, n, r)
                },
                execCommand: function(e, t, n, r) {
                    return this.editorCommands.execCommand(e, t, n, r)
                },
                queryCommandState: function(e) {
                    return this.editorCommands.queryCommandState(e)
                },
                queryCommandValue: function(e) {
                    return this.editorCommands.queryCommandValue(e)
                },
                queryCommandSupported: function(e) {
                    return this.editorCommands.queryCommandSupported(e)
                },
                show: function() {
                    var e = this;
                    e.hidden && (e.hidden = !1, e.inline ? e.getBody().contentEditable = !0 : (B.show(e.getContainer()), B.hide(e.id)), e.load(), e.fire("show"))
                },
                hide: function() {
                    var e = this,
                        t = e.getDoc();
                    e.hidden || (V && t && !e.inline && t.execCommand("SelectAll"), e.save(), e.inline ? (e.getBody().contentEditable = !1, e == e.editorManager.focusedEditor && (e.editorManager.focusedEditor = null)) : (B.hide(e.getContainer()), B.setStyle(e.id, "display", e.orgDisplay)), e.hidden = !0, e.fire("hide"))
                },
                isHidden: function() {
                    return !!this.hidden
                },
                setProgressState: function(e, t) {
                    this.fire("ProgressState", {
                        state: e,
                        time: t
                    })
                },
                load: function(e) {
                    var n = this,
                        r = n.getElement(),
                        i;
                    return r ? (e = e || {}, e.load = !0, i = n.setContent(r.value !== t ? r.value : r.innerHTML, e), e.element = r, e.no_events || n.fire("LoadContent", e), e.element = r = null, i) : void 0
                },
                save: function(e) {
                    var t = this,
                        n = t.getElement(),
                        r, i;
                    if (n && t.initialized) return e = e || {}, e.save = !0, e.element = n, r = e.content = t.getContent(e), e.no_events || t.fire("SaveContent", e), "raw" == e.format && t.fire("RawSaveContent", e), r = e.content, /TEXTAREA|INPUT/i.test(n.nodeName) ? n.value = r : (t.inline || (n.innerHTML = r), (i = B.getParent(t.id, "form")) && P(i.elements, function(e) {
                        return e.name == t.id ? (e.value = r, !1) : void 0
                    })), e.element = n = null, e.set_dirty !== !1 && t.setDirty(!1), r
                },
                setContent: function(e, t) {
                    var n = this,
                        r = n.getBody(),
                        i, o;
                    return t = t || {}, t.format = t.format || "html", t.set = !0, t.content = e, t.no_events || n.fire("BeforeSetContent", t), e = t.content, 0 === e.length || /^\s+$/.test(e) ? (o = V && 11 > V ? "" : '<br data-mce-bogus="1">', "TABLE" == r.nodeName ? e = "<tr><td>" + o + "</td></tr>" : /^(UL|OL)$/.test(r.nodeName) && (e = "<li>" + o + "</li>"), i = n.settings.forced_root_block, i && n.schema.isValidChild(r.nodeName.toLowerCase(), i.toLowerCase()) ? (e = o, e = n.dom.createHTML(i, n.settings.forced_root_block_attrs, e)) : V || e || (e = '<br data-mce-bogus="1">'), n.dom.setHTML(r, e), n.fire("SetContent", t)) : ("raw" !== t.format && (e = new s({
                        validate: n.validate
                    }, n.schema).serialize(n.parser.parse(e, {
                        isRootContent: !0
                    }))), t.content = I(e), n.dom.setHTML(r, t.content), t.no_events || n.fire("SetContent", t)), t.content
                },
                getContent: function(e) {
                    var t = this,
                        n, r = t.getBody();
                    return e = e || {}, e.format = e.format || "html", e.get = !0, e.getInner = !0, e.no_events || t.fire("BeforeGetContent", e), n = "raw" == e.format ? t.serializer.getTrimmedContent() : "text" == e.format ? r.innerText || r.textContent : t.serializer.serialize(r, e), "text" != e.format ? e.content = I(n) : e.content = n, e.no_events || t.fire("GetContent", e), e.content
                },
                insertContent: function(e, t) {
                    t && (e = L({
                        content: e
                    }, t)), this.execCommand("mceInsertContent", !1, e)
                },
                isDirty: function() {
                    return !this.isNotDirty
                },
                setDirty: function(e) {
                    var t = !this.isNotDirty;
                    this.isNotDirty = !e, e && e != t && this.fire("dirty")
                },
                setMode: function(e) {
                    S.setMode(this, e)
                },
                getContainer: function() {
                    var e = this;
                    return e.container || (e.container = B.get(e.editorContainer || e.id + "_parent")), e.container
                },
                getContentAreaContainer: function() {
                    return this.contentAreaContainer
                },
                getElement: function() {
                    return this.targetElm || (this.targetElm = B.get(this.id)), this.targetElm
                },
                getWin: function() {
                    var e = this,
                        t;
                    return e.contentWindow || (t = e.iframeElement, t && (e.contentWindow = t.contentWindow)), e.contentWindow
                },
                getDoc: function() {
                    var e = this,
                        t;
                    return e.contentDocument || (t = e.getWin(), t && (e.contentDocument = t.document)), e.contentDocument
                },
                getBody: function() {
                    return this.bodyElement || this.getDoc().body
                },
                convertURL: function(e, t, n) {
                    var r = this,
                        i = r.settings;
                    return i.urlconverter_callback ? r.execCallback("urlconverter_callback", e, n, !0, t) : !i.convert_urls || n && "LINK" == n.nodeName || 0 === e.indexOf("file:") || 0 === e.length ? e : i.relative_urls ? r.documentBaseURI.toRelative(e) : e = r.documentBaseURI.toAbsolute(e, i.remove_script_host)
                },
                addVisual: function(e) {
                    var n = this,
                        r = n.settings,
                        i = n.dom,
                        o;
                    e = e || n.getBody(), n.hasVisual === t && (n.hasVisual = r.visual), P(i.select("table,a", e), function(e) {
                        var t;
                        switch (e.nodeName) {
                            case "TABLE":
                                return o = r.visual_table_class || "mce-item-table", t = i.getAttrib(e, "border"), void(t && "0" != t || !n.hasVisual ? i.removeClass(e, o) : i.addClass(e, o));
                            case "A":
                                return void(i.getAttrib(e, "href", !1) || (t = i.getAttrib(e, "name") || e.id, o = r.visual_anchor_class || "mce-item-anchor", t && n.hasVisual ? i.addClass(e, o) : i.removeClass(e, o)))
                        }
                    }), n.fire("VisualAid", {
                        element: e,
                        hasVisual: n.hasVisual
                    })
                },
                remove: function() {
                    var e = this;
                    e.removed || (e.save(), e.removed = 1, e.unbindAllNativeEvents(), e.hasHiddenInput && B.remove(e.getElement().nextSibling), e.inline || (V && 10 > V && e.getDoc().execCommand("SelectAll", !1, null), B.setStyle(e.id, "display", e.orgDisplay), e.getBody().onload = null), e.fire("remove"), e.editorManager.remove(e), B.remove(e.getContainer()), e._selectionOverrides.destroy(), e.editorUpload.destroy(), e.destroy())
                },
                destroy: function(e) {
                    var t = this,
                        n;
                    if (!t.destroyed) {
                        if (!e && !t.removed) return void t.remove();
                        e || (t.editorManager.off("beforeunload", t._beforeUnload), t.theme && t.theme.destroy && t.theme.destroy(), t.selection.destroy(), t.dom.destroy()), n = t.formElement, n && (n._mceOldSubmit && (n.submit = n._mceOldSubmit, n._mceOldSubmit = null), B.unbind(n, "submit reset", t.formEventDelegate)), t.contentAreaContainer = t.formElement = t.container = t.editorContainer = null, t.bodyElement = t.contentDocument = t.contentWindow = null, t.iframeElement = t.targetElm = null, t.selection && (t.selection = t.selection.win = t.selection.dom = t.selection.dom.doc = null), t.destroyed = 1
                    }
                },
                uploadImages: function(e) {
                    return this.editorUpload.uploadImages(e)
                },
                _scanForImages: function() {
                    return this.editorUpload.scanForImages()
                },
                _refreshContentEditable: function() {
                    var e = this,
                        t, n;
                    e._isHidden() && (t = e.getBody(), n = t.parentNode, n.removeChild(t), n.appendChild(t), t.focus())
                },
                _isHidden: function() {
                    var e;
                    return W ? (e = this.selection.getSel(), !e || !e.rangeCount || 0 === e.rangeCount) : 0
                }
            }, L(A.prototype, _), A
        }), r(Ge, [], function() {
            var e = {},
                t = "en";
            return {
                setCode: function(e) {
                    e && (t = e, this.rtl = this.data[e] ? "rtl" === this.data[e]._dir : !1)
                },
                getCode: function() {
                    return t
                },
                rtl: !1,
                add: function(t, n) {
                    var r = e[t];
                    r || (e[t] = r = {});
                    for (var i in n) r[i] = n[i];
                    this.setCode(t)
                },
                translate: function(n) {
                    var r;
                    if (r = e[t], r || (r = {}), "undefined" == typeof n) return n;
                    if ("string" != typeof n && n.raw) return n.raw;
                    if (n.push) {
                        var i = n.slice(1);
                        n = (r[n[0]] || n[0]).replace(/\{([0-9]+)\}/g, function(e, t) {
                            return i[t]
                        })
                    }
                    return (r[n] || n).replace(/{context:\w+}$/, "")
                },
                data: e
            }
        }), r(Je, [w, u, h], function(e, t, n) {
            function r(e) {
                function l() {
                    try {
                        return document.activeElement
                    } catch (e) {
                        return document.body
                    }
                }
    
                function c(e, t) {
                    if (t && t.startContainer) {
                        if (!e.isChildOf(t.startContainer, e.getRoot()) || !e.isChildOf(t.endContainer, e.getRoot())) return;
                        return {
                            startContainer: t.startContainer,
                            startOffset: t.startOffset,
                            endContainer: t.endContainer,
                            endOffset: t.endOffset
                        }
                    }
                    return t
                }
    
                function u(e, t) {
                    var n;
                    return t.startContainer ? (n = e.getDoc().createRange(), n.setStart(t.startContainer, t.startOffset), n.setEnd(t.endContainer, t.endOffset)) : n = t, n
                }
    
                function d(e) {
                    return !!s.getParent(e, r.isEditorUIElement)
                }
    
                function f(r) {
                    var f = r.editor;
                    f.on("init", function() {
                        (f.inline || n.ie) && ("onbeforedeactivate" in document && n.ie < 9 ? f.dom.bind(f.getBody(), "beforedeactivate", function(e) {
                            if (e.target == f.getBody()) try {
                                f.lastRng = f.selection.getRng()
                            } catch (t) {}
                        }) : f.on("nodechange mouseup keyup", function(e) {
                            var t = l();
                            "nodechange" == e.type && e.selectionChange || (t && t.id == f.id + "_ifr" && (t = f.getBody()), f.dom.isChildOf(t, f.getBody()) && (f.lastRng = f.selection.getRng()))
                        }), n.webkit && !i && (i = function() {
                            var t = e.activeEditor;
                            if (t && t.selection) {
                                var n = t.selection.getRng();
                                n && !n.collapsed && (f.lastRng = n)
                            }
                        }, s.bind(document, "selectionchange", i)))
                    }), f.on("setcontent", function() {
                        f.lastRng = null
                    }), f.on("mousedown", function() {
                        f.selection.lastFocusBookmark = null
                    }), f.on("focusin", function() {
                        var t = e.focusedEditor,
                            n;
                        f.selection.lastFocusBookmark && (n = u(f, f.selection.lastFocusBookmark), f.selection.lastFocusBookmark = null, f.selection.setRng(n)), t != f && (t && t.fire("blur", {
                            focusedEditor: f
                        }), e.setActive(f), e.focusedEditor = f, f.fire("focus", {
                            blurredEditor: t
                        }), f.focus(!0)), f.lastRng = null
                    }), f.on("focusout", function() {
                        t.setEditorTimeout(f, function() {
                            var t = e.focusedEditor;
                            d(l()) || t != f || (f.fire("blur", {
                                focusedEditor: null
                            }), e.focusedEditor = null, f.selection && (f.selection.lastFocusBookmark = null))
                        })
                    }), o || (o = function(t) {
                        var n = e.activeEditor;
                        n && t.target.ownerDocument == document && (n.selection && t.target != n.getBody() && (n.selection.lastFocusBookmark = c(n.dom, n.lastRng)), t.target == document.body || d(t.target) || e.focusedEditor != n || (n.fire("blur", {
                            focusedEditor: null
                        }), e.focusedEditor = null))
                    }, s.bind(document, "focusin", o)), f.inline && !a && (a = function(t) {
                        var n = e.activeEditor;
                        if (n.inline && !n.dom.isChildOf(t.target, n.getBody())) {
                            var r = n.selection.getRng();
                            r.collapsed || (n.lastRng = r)
                        }
                    }, s.bind(document, "mouseup", a))
                }
    
                function h(t) {
                    e.focusedEditor == t.editor && (e.focusedEditor = null), e.activeEditor || (s.unbind(document, "selectionchange", i), s.unbind(document, "focusin", o), s.unbind(document, "mouseup", a), i = o = a = null)
                }
                e.on("AddEditor", f), e.on("RemoveEditor", h)
            }
            var i, o, a, s = e.DOM;
            return r.isEditorUIElement = function(e) {
                return -1 !== e.className.toString().indexOf("mce-")
            }, r
        }), r(Qe, [Ke, g, w, te, h, m, oe, Ge, Je], function(e, t, n, r, i, o, a, s, l) {
            function c(e) {
                m(b.editors, function(t) {
                    t.fire("ResizeWindow", e)
                })
            }
    
            function u(e, n) {
                n !== C && (n ? t(window).on("resize", c) : t(window).off("resize", c), C = n)
            }
    
            function d(e) {
                var t = b.editors,
                    n;
                delete t[e.id];
                for (var r = 0; r < t.length; r++)
                    if (t[r] == e) {
                        t.splice(r, 1), n = !0;
                        break
                    }
                return b.activeEditor == e && (b.activeEditor = t[0]), b.focusedEditor == e && (b.focusedEditor = null), n
            }
    
            function f(e) {
                return e && !(e.getContainer() || e.getBody()).parentNode && (d(e), e.unbindAllNativeEvents(), e.destroy(!0), e = null), e
            }
            var h = n.DOM,
                p = o.explode,
                m = o.each,
                g = o.extend,
                v = 0,
                y, b, C = !1;
            return b = {
                $: t,
                majorVersion: "4",
                minorVersion: "3.3",
                releaseDate: "2016-01-14",
                editors: [],
                i18n: s,
                activeEditor: null,
                setup: function() {
                    var e = this,
                        t, n, i = "",
                        o, a;
                    if (n = document.location.href, /^[^:]+:\/\/\/?[^\/]+\//.test(n) && (n = n.replace(/[\?#].*$/, "").replace(/[\/\\][^\/]+$/, ""), /[\/\\]$/.test(n) || (n += "/")), o = window.tinymce || window.tinyMCEPreInit) t = o.base || o.baseURL, i = o.suffix;
                    else {
                        for (var s = document.getElementsByTagName("script"), c = 0; c < s.length; c++) {
                            a = s[c].src;
                            var u = a.substring(a.lastIndexOf("/"));
                            if (/tinymce(\.full|\.jquery|)(\.min|\.dev|)\.js/.test(a)) {
                                -1 != u.indexOf(".min") && (i = ".min"), t = a.substring(0, a.lastIndexOf("/"));
                                break
                            }
                        }!t && document.currentScript && (a = document.currentScript.src, -1 != a.indexOf(".min") && (i = ".min"), t = a.substring(0, a.lastIndexOf("/")))
                    }
                    e.baseURL = new r(n).toAbsolute(t), e.documentBaseURL = n, e.baseURI = new r(e.baseURL), e.suffix = i, e.focusManager = new l(e)
                },
                init: function(t) {
                    function n(e) {
                        var t = e.id;
                        return t || (t = e.name, t = t && !h.get(t) ? e.name : h.uniqueId(), e.setAttribute("id", t)), t
                    }
    
                    function r(t, n, r) {
                        if (!f(s.get(t))) {
                            var i = new e(t, n, s);
                            i.targetElm = i.targetElm || r, l.push(i), i.render()
                        }
                    }
    
                    function i(e) {
                        var n = t[e];
                        if (n) return n.apply(s, Array.prototype.slice.call(arguments, 2))
                    }
    
                    function o(e, t) {
                        return t.constructor === RegExp ? t.test(e.className) : h.hasClass(e, t)
                    }
    
                    function a() {
                        var e, s;
                        if (h.unbind(window, "ready", a), i("onpageload"), t.types) return void m(t.types, function(e) {
                            m(h.select(e.selector), function(i) {
                                r(n(i), g({}, t, e), i)
                            })
                        });
                        if (t.selector) return void m(h.select(t.selector), function(e) {
                            r(n(e), t, e)
                        });
                        switch (t.target && r(n(t.target), t), t.mode) {
                            case "exact":
                                e = t.elements || "", e.length > 0 && m(p(e), function(e) {
                                    var n;
                                    (n = h.get(e)) ? r(e, t, n): m(document.forms, function(n) {
                                        m(n.elements, function(n) {
                                            n.name === e && (e = "mce_editor_" + v++, h.setAttrib(n, "id", e), r(e, t, n))
                                        })
                                    })
                                });
                                break;
                            case "textareas":
                            case "specific_textareas":
                                m(h.select("textarea"), function(e) {
                                    t.editor_deselector && o(e, t.editor_deselector) || (!t.editor_selector || o(e, t.editor_selector)) && r(n(e), t, e)
                                })
                        }
                        t.oninit && (e = s = 0, m(l, function(t) {
                            s++, t.initialized ? e++ : t.on("init", function() {
                                e++, e == s && i("oninit")
                            }), e == s && i("oninit")
                        }))
                    }
                    var s = this,
                        l = [];
                    s.settings = t, h.bind(window, "ready", a)
                },
                get: function(e) {
                    return arguments.length ? e in this.editors ? this.editors[e] : null : this.editors
                },
                add: function(e) {
                    var t = this,
                        n = t.editors;
                    return n[e.id] = e, n.push(e), u(n, !0), t.activeEditor = e, t.fire("AddEditor", {
                        editor: e
                    }), y || (y = function() {
                        t.fire("BeforeUnload")
                    }, h.bind(window, "beforeunload", y)), e
                },
                createEditor: function(t, n) {
                    return this.add(new e(t, n, this))
                },
                remove: function(e) {
                    var t = this,
                        n, r = t.editors,
                        i; {
                        if (e) return "string" == typeof e ? (e = e.selector || e, void m(h.select(e), function(e) {
                            i = r[e.id], i && t.remove(i)
                        })) : (i = e, r[i.id] ? (d(i) && t.fire("RemoveEditor", {
                            editor: i
                        }), r.length || h.unbind(window, "beforeunload", y), i.remove(), u(r, r.length > 0), i) : null);
                        for (n = r.length - 1; n >= 0; n--) t.remove(r[n])
                    }
                },
                execCommand: function(t, n, r) {
                    var i = this,
                        o = i.get(r);
                    switch (t) {
                        case "mceAddEditor":
                            return i.get(r) || new e(r, i.settings, i).render(), !0;
                        case "mceRemoveEditor":
                            return o && o.remove(), !0;
                        case "mceToggleEditor":
                            return o ? (o.isHidden() ? o.show() : o.hide(), !0) : (i.execCommand("mceAddEditor", 0, r), !0)
                    }
                    return i.activeEditor ? i.activeEditor.execCommand(t, n, r) : !1
                },
                triggerSave: function() {
                    m(this.editors, function(e) {
                        e.save()
                    })
                },
                addI18n: function(e, t) {
                    s.add(e, t)
                },
                translate: function(e) {
                    return s.translate(e)
                },
                setActive: function(e) {
                    var t = this.activeEditor;
                    this.activeEditor != e && (t && t.fire("deactivate", {
                        relatedTarget: e
                    }), e.fire("activate", {
                        relatedTarget: t
                    })), this.activeEditor = e
                }
            }, g(b, a), b.setup(), window.tinymce = window.tinyMCE = b, b
        }), r(Ze, [Qe, m], function(e, t) {
            var n = t.each,
                r = t.explode;
            e.on("AddEditor", function(e) {
                var t = e.editor;
                t.on("preInit", function() {
                    function e(e, t) {
                        n(t, function(t, n) {
                            t && s.setStyle(e, n, t)
                        }), s.rename(e, "span")
                    }
    
                    function i(e) {
                        s = t.dom, l.convert_fonts_to_spans && n(s.select("font,u,strike", e.node), function(e) {
                            o[e.nodeName.toLowerCase()](s, e)
                        })
                    }
                    var o, a, s, l = t.settings;
                    l.inline_styles && (a = r(l.font_size_legacy_values), o = {
                        font: function(t, n) {
                            e(n, {
                                backgroundColor: n.style.backgroundColor,
                                color: n.color,
                                fontFamily: n.face,
                                fontSize: a[parseInt(n.size, 10) - 1]
                            })
                        },
                        u: function(n, r) {
                            "html4" === t.settings.schema && e(r, {
                                textDecoration: "underline"
                            })
                        },
                        strike: function(t, n) {
                            e(n, {
                                textDecoration: "line-through"
                            })
                        }
                    }, t.on("PreProcess SetContent", i))
                })
            })
        }), r(et, [oe, m], function(e, t) {
            var n = {
                send: function(e) {
                    function r() {
                        !e.async || 4 == i.readyState || o++ > 1e4 ? (e.success && 1e4 > o && 200 == i.status ? e.success.call(e.success_scope, "" + i.responseText, i, e) : e.error && e.error.call(e.error_scope, o > 1e4 ? "TIMED_OUT" : "GENERAL", i, e), i = null) : setTimeout(r, 10)
                    }
                    var i, o = 0;
                    if (e.scope = e.scope || this, e.success_scope = e.success_scope || e.scope, e.error_scope = e.error_scope || e.scope, e.async = e.async === !1 ? !1 : !0, e.data = e.data || "", n.fire("beforeInitialize", {
                            settings: e
                        }), i = new XMLHttpRequest) {
                        if (i.overrideMimeType && i.overrideMimeType(e.content_type), i.open(e.type || (e.data ? "POST" : "GET"), e.url, e.async), e.crossDomain && (i.withCredentials = !0), e.content_type && i.setRequestHeader("Content-Type", e.content_type), e.requestheaders && t.each(e.requestheaders, function(e) {
                                i.setRequestHeader(e.key, e.value)
                            }), i.setRequestHeader("X-Requested-With", "XMLHttpRequest"), i = n.fire("beforeSend", {
                                xhr: i,
                                settings: e
                            }).xhr, i.send(e.data), !e.async) return r();
                        setTimeout(r, 10)
                    }
                }
            };
            return t.extend(n, e), n
        }), r(tt, [], function() {
            function e(t, n) {
                var r, i, o, a;
                if (n = n || '"', null === t) return "null";
                if (o = typeof t, "string" == o) return i = "\bb	t\nn\ff\rr\"\"''\\\\", n + t.replace(/([\u0080-\uFFFF\x00-\x1f\"\'\\])/g, function(e, t) {
                    return '"' === n && "'" === e ? e : (r = i.indexOf(t), r + 1 ? "\\" + i.charAt(r + 1) : (e = t.charCodeAt().toString(16), "\\u" + "0000".substring(e.length) + e))
                }) + n;
                if ("object" == o) {
                    if (t.hasOwnProperty && "[object Array]" === Object.prototype.toString.call(t)) {
                        for (r = 0, i = "["; r < t.length; r++) i += (r > 0 ? "," : "") + e(t[r], n);
                        return i + "]"
                    }
                    i = "{";
                    for (a in t) t.hasOwnProperty(a) && (i += "function" != typeof t[a] ? (i.length > 1 ? "," + n : n) + a + n + ":" + e(t[a], n) : "");
                    return i + "}"
                }
                return "" + t
            }
            return {
                serialize: e,
                parse: function(e) {
                    try {
                        return window[String.fromCharCode(101) + "val"]("(" + e + ")")
                    } catch (t) {}
                }
            }
        }), r(nt, [tt, et, m], function(e, t, n) {
            function r(e) {
                this.settings = i({}, e), this.count = 0
            }
            var i = n.extend;
            return r.sendRPC = function(e) {
                return (new r).send(e)
            }, r.prototype = {
                send: function(n) {
                    var r = n.error,
                        o = n.success;
                    n = i(this.settings, n), n.success = function(t, i) {
                        t = e.parse(t), "undefined" == typeof t && (t = {
                            error: "JSON Parse error."
                        }), t.error ? r.call(n.error_scope || n.scope, t.error, i) : o.call(n.success_scope || n.scope, t.result)
                    }, n.error = function(e, t) {
                        r && r.call(n.error_scope || n.scope, e, t)
                    }, n.data = e.serialize({
                        id: n.id || "c" + this.count++,
                        method: n.method,
                        params: n.params
                    }), n.content_type = "application/json", t.send(n)
                }
            }, r
        }), r(rt, [w], function(e) {
            return {
                callbacks: {},
                count: 0,
                send: function(n) {
                    var r = this,
                        i = e.DOM,
                        o = n.count !== t ? n.count : r.count,
                        a = "tinymce_jsonp_" + o;
                    r.callbacks[o] = function(e) {
                        i.remove(a), delete r.callbacks[o], n.callback(e)
                    }, i.add(i.doc.body, "script", {
                        id: a,
                        src: n.url,
                        type: "text/javascript"
                    }), r.count++
                }
            }
        }), r(it, [], function() {
            function e() {
                s = [];
                for (var e in a) s.push(e);
                i.length = s.length
            }
    
            function n() {
                function n(e) {
                    var n, r;
                    return r = e !== t ? u + e : i.indexOf(",", u), -1 === r || r > i.length ? null : (n = i.substring(u, r), u = r + 1, n)
                }
                var r, i, s, u = 0;
                if (a = {}, c) {
                    o.load(l), i = o.getAttribute(l) || "";
                    do {
                        var d = n();
                        if (null === d) break;
                        if (r = n(parseInt(d, 32) || 0), null !== r) {
                            if (d = n(), null === d) break;
                            s = n(parseInt(d, 32) || 0), r && (a[r] = s)
                        }
                    } while (null !== r);
                    e()
                }
            }
    
            function r() {
                var t, n = "";
                if (c) {
                    for (var r in a) t = a[r], n += (n ? "," : "") + r.length.toString(32) + "," + r + "," + t.length.toString(32) + "," + t;
                    o.setAttribute(l, n);
                    try {
                        o.save(l)
                    } catch (i) {}
                    e()
                }
            }
            var i, o, a, s, l, c;
            try {
                if (window.localStorage) return localStorage
            } catch (u) {}
            return l = "tinymce", o = document.documentElement, c = !!o.addBehavior, c && o.addBehavior("#default#userData"), i = {
                key: function(e) {
                    return s[e]
                },
                getItem: function(e) {
                    return e in a ? a[e] : null
                },
                setItem: function(e, t) {
                    a[e] = "" + t, r()
                },
                removeItem: function(e) {
                    delete a[e], r()
                },
                clear: function() {
                    a = {}, r()
                }
            }, n(), i
        }), r(ot, [w, d, E, N, m, h], function(e, t, n, r, i, o) {
            var a = window.tinymce;
            return a.DOM = e.DOM, a.ScriptLoader = n.ScriptLoader, a.PluginManager = r.PluginManager, a.ThemeManager = r.ThemeManager, a.dom = a.dom || {}, a.dom.Event = t.Event, i.each(i, function(e, t) {
                a[t] = e
            }), i.each("isOpera isWebKit isIE isGecko isMac".split(" "), function(e) {
                a[e] = o[e.substr(2).toLowerCase()]
            }), {}
        }), r(at, [ne, m], function(e, t) {
            return e.extend({
                Defaults: {
                    firstControlClass: "first",
                    lastControlClass: "last"
                },
                init: function(e) {
                    this.settings = t.extend({}, this.Defaults, e)
                },
                preRender: function(e) {
                    e.bodyClasses.add(this.settings.containerClass)
                },
                applyClasses: function(e) {
                    var t = this,
                        n = t.settings,
                        r, i, o, a;
                    r = n.firstControlClass, i = n.lastControlClass, e.each(function(e) {
                        e.classes.remove(r).remove(i).add(n.controlClass), e.visible() && (o || (o = e), a = e)
                    }), o && o.classes.add(r), a && a.classes.add(i)
                },
                renderHtml: function(e) {
                    var t = this,
                        n = "";
                    return t.applyClasses(e.items()), e.items().each(function(e) {
                        n += e.renderHtml()
                    }), n
                },
                recalc: function() {},
                postRender: function() {},
                isNative: function() {
                    return !1
                }
            })
        }), r(st, [at], function(e) {
            return e.extend({
                Defaults: {
                    containerClass: "abs-layout",
                    controlClass: "abs-layout-item"
                },
                recalc: function(e) {
                    e.items().filter(":visible").each(function(e) {
                        var t = e.settings;
                        e.layoutRect({
                            x: t.x,
                            y: t.y,
                            w: t.w,
                            h: t.h
                        }), e.recalc && e.recalc()
                    })
                },
                renderHtml: function(e) {
                    return '<div id="' + e._id + '-absend" class="' + e.classPrefix + 'abs-end"></div>' + this._super(e)
                }
            })
        }), r(lt, [ke], function(e) {
            return e.extend({
                Defaults: {
                    classes: "widget btn",
                    role: "button"
                },
                init: function(e) {
                    var t = this,
                        n;
                    t._super(e), e = t.settings, n = t.settings.size, t.on("click mousedown", function(e) {
                        e.preventDefault()
                    }), t.on("touchstart", function(e) {
                        t.fire("click", e), e.preventDefault()
                    }), e.subtype && t.classes.add(e.subtype), n && t.classes.add("btn-" + n), e.icon && t.icon(e.icon)
                },
                icon: function(e) {
                    return arguments.length ? (this.state.set("icon", e), this) : this.state.get("icon")
                },
                repaint: function() {
                    var e = this.getEl().firstChild,
                        t;
                    e && (t = e.style, t.width = t.height = "100%"), this._super()
                },
                renderHtml: function() {
                    var e = this,
                        t = e._id,
                        n = e.classPrefix,
                        r = e.state.get("icon"),
                        i, o = e.state.get("text"),
                        a = "";
                    return i = e.settings.image, i ? (r = "none", "string" != typeof i && (i = window.getSelection ? i[0] : i[1]), i = " style=\"background-image: url('" + i + "')\"") : i = "", o && (e.classes.add("btn-has-text"), a = '<span class="' + n + 'txt">' + e.encode(o) + "</span>"), r = e.settings.icon ? n + "ico " + n + "i-" + r : "", '<div id="' + t + '" class="' + e.classes + '" tabindex="-1" aria-labelledby="' + t + '"><button role="presentation" type="button" tabindex="-1">' + (r ? '<i class="' + r + '"' + i + "></i>" : "") + a + "</button></div>"
                },
                bindStates: function() {
                    function e(e) {
                        var i = n("span." + r, t.getEl());
                        e ? (i[0] || (n("button:first", t.getEl()).append('<span class="' + r + '"></span>'), i = n("span." + r, t.getEl())), i.html(t.encode(e))) : i.remove(), t.classes.toggle("btn-has-text", !!e)
                    }
                    var t = this,
                        n = t.$,
                        r = t.classPrefix + "txt";
                    return t.state.on("change:text", function(t) {
                        e(t.value)
                    }), t.state.on("change:icon", function(n) {
                        var r = n.value,
                            i = t.classPrefix;
                        t.settings.icon = r, r = r ? i + "ico " + i + "i-" + t.settings.icon : "";
                        var o = t.getEl().firstChild,
                            a = o.getElementsByTagName("i")[0];
                        r ? (a && a == o.firstChild || (a = document.createElement("i"), o.insertBefore(a, o.firstChild)), a.className = r) : a && o.removeChild(a), e(t.state.get("text"))
                    }), t._super()
                }
            })
        }), r(ct, [ge], function(e) {
            return e.extend({
                Defaults: {
                    defaultType: "button",
                    role: "group"
                },
                renderHtml: function() {
                    var e = this,
                        t = e._layout;
                    return e.classes.add("btn-group"), e.preRender(), t.preRender(e), '<div id="' + e._id + '" class="' + e.classes + '"><div id="' + e._id + '-body">' + (e.settings.html || "") + t.renderHtml(e) + "</div></div>"
                }
            })
        }), r(ut, [ke], function(e) {
            return e.extend({
                Defaults: {
                    classes: "checkbox",
                    role: "checkbox",
                    checked: !1
                },
                init: function(e) {
                    var t = this;
                    t._super(e), t.on("click mousedown", function(e) {
                        e.preventDefault()
                    }), t.on("click", function(e) {
                        e.preventDefault(), t.disabled() || t.checked(!t.checked())
                    }), t.checked(t.settings.checked);
                },
                checked: function(e) {
                    return arguments.length ? (this.state.set("checked", e), this) : this.state.get("checked")
                },
                value: function(e) {
                    return arguments.length ? this.checked(e) : this.checked()
                },
                renderHtml: function() {
                    var e = this,
                        t = e._id,
                        n = e.classPrefix;
                    return '<div id="' + t + '" class="' + e.classes + '" unselectable="on" aria-labelledby="' + t + '-al" tabindex="-1"><i class="' + n + "ico " + n + 'i-checkbox"></i><span id="' + t + '-al" class="' + n + 'label">' + e.encode(e.state.get("text")) + "</span></div>"
                },
                bindStates: function() {
                    function e(e) {
                        t.classes.toggle("checked", e), t.aria("checked", e)
                    }
                    var t = this;
                    return t.state.on("change:text", function(e) {
                        t.getEl("al").firstChild.data = t.translate(e.value)
                    }), t.state.on("change:checked change:value", function(n) {
                        t.fire("change"), e(n.value)
                    }), t.state.on("change:icon", function(e) {
                        var n = e.value,
                            r = t.classPrefix;
                        if ("undefined" == typeof n) return t.settings.icon;
                        t.settings.icon = n, n = n ? r + "ico " + r + "i-" + t.settings.icon : "";
                        var i = t.getEl().firstChild,
                            o = i.getElementsByTagName("i")[0];
                        n ? (o && o == i.firstChild || (o = document.createElement("i"), i.insertBefore(o, i.firstChild)), o.className = n) : o && i.removeChild(o)
                    }), t.state.get("checked") && e(!0), t._super()
                }
            })
        }), r(dt, [ke, pe, ce, g], function(e, t, n, r) {
            return e.extend({
                init: function(e) {
                    var t = this;
                    t._super(e), e = t.settings, t.classes.add("combobox"), t.subinput = !0, t.ariaTarget = "inp", e.menu = e.menu || e.values, e.menu && (e.icon = "caret"), t.on("click", function(n) {
                        var i = n.target,
                            o = t.getEl();
                        if (r.contains(o, i) || i == o)
                            for (; i && i != o;) i.id && -1 != i.id.indexOf("-open") && (t.fire("action"), e.menu && (t.showMenu(), n.aria && t.menu.items()[0].focus())), i = i.parentNode
                    }), t.on("keydown", function(e) {
                        "INPUT" == e.target.nodeName && 13 == e.keyCode && t.parents().reverse().each(function(n) {
                            var r = t.state.get("value"),
                                i = t.getEl("inp").value;
                            return e.preventDefault(), t.state.set("value", i), r != i && t.fire("change"), n.hasEventListeners("submit") && n.toJSON ? (n.fire("submit", {
                                data: n.toJSON()
                            }), !1) : void 0
                        })
                    }), t.on("keyup", function(e) {
                        "INPUT" == e.target.nodeName && t.state.set("value", e.target.value)
                    })
                },
                showMenu: function() {
                    var e = this,
                        n = e.settings,
                        r;
                    e.menu || (r = n.menu || [], r.length ? r = {
                        type: "menu",
                        items: r
                    } : r.type = r.type || "menu", e.menu = t.create(r).parent(e).renderTo(e.getContainerElm()), e.fire("createmenu"), e.menu.reflow(), e.menu.on("cancel", function(t) {
                        t.control === e.menu && e.focus()
                    }), e.menu.on("show hide", function(t) {
                        t.control.items().each(function(t) {
                            t.active(t.value() == e.value())
                        })
                    }).fire("show"), e.menu.on("select", function(t) {
                        e.value(t.control.value())
                    }), e.on("focusin", function(t) {
                        "INPUT" == t.target.tagName.toUpperCase() && e.menu.hide()
                    }), e.aria("expanded", !0)), e.menu.show(), e.menu.layoutRect({
                        w: e.layoutRect().w
                    }), e.menu.moveRel(e.getEl(), e.isRtl() ? ["br-tr", "tr-br"] : ["bl-tl", "tl-bl"])
                },
                focus: function() {
                    this.getEl("inp").focus()
                },
                repaint: function() {
                    var e = this,
                        t = e.getEl(),
                        i = e.getEl("open"),
                        o = e.layoutRect(),
                        a, s;
                    a = i ? o.w - n.getSize(i).width - 10 : o.w - 10;
                    var l = document;
                    return l.all && (!l.documentMode || l.documentMode <= 8) && (s = e.layoutRect().h - 2 + "px"), r(t.firstChild).css({
                        width: a,
                        lineHeight: s
                    }), e._super(), e
                },
                postRender: function() {
                    var e = this;
                    return r(this.getEl("inp")).on("change", function(t) {
                        e.state.set("value", t.target.value), e.fire("change", t)
                    }), e._super()
                },
                renderHtml: function() {
                    var e = this,
                        t = e._id,
                        n = e.settings,
                        r = e.classPrefix,
                        i = e.state.get("value") || "",
                        o, a, s = "",
                        l = "";
                    return "spellcheck" in n && (l += ' spellcheck="' + n.spellcheck + '"'), n.maxLength && (l += ' maxlength="' + n.maxLength + '"'), n.size && (l += ' size="' + n.size + '"'), n.subtype && (l += ' type="' + n.subtype + '"'), e.disabled() && (l += ' disabled="disabled"'), o = n.icon, o && "caret" != o && (o = r + "ico " + r + "i-" + n.icon), a = e.state.get("text"), (o || a) && (s = '<div id="' + t + '-open" class="' + r + "btn " + r + 'open" tabIndex="-1" role="button"><button id="' + t + '-action" type="button" hidefocus="1" tabindex="-1">' + ("caret" != o ? '<i class="' + o + '"></i>' : '<i class="' + r + 'caret"></i>') + (a ? (o ? " " : "") + a : "") + "</button></div>", e.classes.add("has-open")), '<div id="' + t + '" class="' + e.classes + '"><input id="' + t + '-inp" class="' + r + 'textbox" value="' + e.encode(i, !1) + '" hidefocus="1"' + l + ' placeholder="' + e.encode(n.placeholder) + '" />' + s + "</div>"
                },
                value: function(e) {
                    return arguments.length ? (this.state.set("value", e), this) : (this.state.get("rendered") && this.state.set("value", this.getEl("inp").value), this.state.get("value"))
                },
                bindStates: function() {
                    var e = this;
                    return e.state.on("change:value", function(t) {
                        e.getEl("inp").value != t.value && (e.getEl("inp").value = t.value)
                    }), e.state.on("change:disabled", function(t) {
                        e.getEl("inp").disabled = t.value
                    }), e._super()
                },
                remove: function() {
                    r(this.getEl("inp")).off(), this._super()
                }
            })
        }), r(ft, [dt], function(e) {
            return e.extend({
                init: function(e) {
                    var t = this;
                    e.spellcheck = !1, e.onaction && (e.icon = "none"), t._super(e), t.classes.add("colorbox"), t.on("change keyup postrender", function() {
                        t.repaintColor(t.value())
                    })
                },
                repaintColor: function(e) {
                    var t = this.getEl().getElementsByTagName("i")[0];
                    if (t) try {
                        t.style.background = e
                    } catch (n) {}
                },
                bindStates: function() {
                    var e = this;
                    return e.state.on("change:value", function(t) {
                        e._rendered && e.repaintColor(t.value)
                    }), e._super()
                }
            })
        }), r(ht, [lt, we], function(e, t) {
            return e.extend({
                showPanel: function() {
                    var e = this,
                        n = e.settings;
                    if (e.active(!0), e.panel) e.panel.show();
                    else {
                        var r = n.panel;
                        r.type && (r = {
                            layout: "grid",
                            items: r
                        }), r.role = r.role || "dialog", r.popover = !0, r.autohide = !0, r.ariaRoot = !0, e.panel = new t(r).on("hide", function() {
                            e.active(!1)
                        }).on("cancel", function(t) {
                            t.stopPropagation(), e.focus(), e.hidePanel()
                        }).parent(e).renderTo(e.getContainerElm()), e.panel.fire("show"), e.panel.reflow()
                    }
                    e.panel.moveRel(e.getEl(), n.popoverAlign || (e.isRtl() ? ["bc-tr", "bc-tc"] : ["bc-tl", "bc-tc"]))
                },
                hidePanel: function() {
                    var e = this;
                    e.panel && e.panel.hide()
                },
                postRender: function() {
                    var e = this;
                    return e.aria("haspopup", !0), e.on("click", function(t) {
                        t.control === e && (e.panel && e.panel.visible() ? e.hidePanel() : (e.showPanel(), e.panel.focus(!!t.aria)))
                    }), e._super()
                },
                remove: function() {
                    return this.panel && (this.panel.remove(), this.panel = null), this._super()
                }
            })
        }), r(pt, [ht, w], function(e, t) {
            var n = t.DOM;
            return e.extend({
                init: function(e) {
                    this._super(e), this.classes.add("colorbutton")
                },
                color: function(e) {
                    return e ? (this._color = e, this.getEl("preview").style.backgroundColor = e, this) : this._color
                },
                resetColor: function() {
                    return this._color = null, this.getEl("preview").style.backgroundColor = null, this
                },
                renderHtml: function() {
                    var e = this,
                        t = e._id,
                        n = e.classPrefix,
                        r = e.state.get("text"),
                        i = e.settings.icon ? n + "ico " + n + "i-" + e.settings.icon : "",
                        o = e.settings.image ? " style=\"background-image: url('" + e.settings.image + "')\"" : "",
                        a = "";
                    return r && (e.classes.add("btn-has-text"), a = '<span class="' + n + 'txt">' + e.encode(r) + "</span>"), '<div id="' + t + '" class="' + e.classes + '" role="button" tabindex="-1" aria-haspopup="true"><button role="presentation" hidefocus="1" type="button" tabindex="-1">' + (i ? '<i class="' + i + '"' + o + "></i>" : "") + '<span id="' + t + '-preview" class="' + n + 'preview"></span>' + a + '</button><button type="button" class="' + n + 'open" hidefocus="1" tabindex="-1"> <i class="' + n + 'caret"></i></button></div>'
                },
                postRender: function() {
                    var e = this,
                        t = e.settings.onclick;
                    return e.on("click", function(r) {
                        r.aria && "down" == r.aria.key || r.control != e || n.getParent(r.target, "." + e.classPrefix + "open") || (r.stopImmediatePropagation(), t.call(e, r))
                    }), delete e.settings.onclick, e._super()
                }
            })
        }), r(mt, [], function() {
            function e(e) {
                function i(e, i, o) {
                    var a, s, l, c, u, d;
                    return a = 0, s = 0, l = 0, e /= 255, i /= 255, o /= 255, u = t(e, t(i, o)), d = n(e, n(i, o)), u == d ? (l = u, {
                        h: 0,
                        s: 0,
                        v: 100 * l
                    }) : (c = e == u ? i - o : o == u ? e - i : o - e, a = e == u ? 3 : o == u ? 1 : 5, a = 60 * (a - c / (d - u)), s = (d - u) / d, l = d, {
                        h: r(a),
                        s: r(100 * s),
                        v: r(100 * l)
                    })
                }
    
                function o(e, i, o) {
                    var a, s, l, c;
                    if (e = (parseInt(e, 10) || 0) % 360, i = parseInt(i, 10) / 100, o = parseInt(o, 10) / 100, i = n(0, t(i, 1)), o = n(0, t(o, 1)), 0 === i) return void(d = f = h = r(255 * o));
                    switch (a = e / 60, s = o * i, l = s * (1 - Math.abs(a % 2 - 1)), c = o - s, Math.floor(a)) {
                        case 0:
                            d = s, f = l, h = 0;
                            break;
                        case 1:
                            d = l, f = s, h = 0;
                            break;
                        case 2:
                            d = 0, f = s, h = l;
                            break;
                        case 3:
                            d = 0, f = l, h = s;
                            break;
                        case 4:
                            d = l, f = 0, h = s;
                            break;
                        case 5:
                            d = s, f = 0, h = l;
                            break;
                        default:
                            d = f = h = 0
                    }
                    d = r(255 * (d + c)), f = r(255 * (f + c)), h = r(255 * (h + c))
                }
    
                function a() {
                    function e(e) {
                        return e = parseInt(e, 10).toString(16), e.length > 1 ? e : "0" + e
                    }
                    return "#" + e(d) + e(f) + e(h)
                }
    
                function s() {
                    return {
                        r: d,
                        g: f,
                        b: h
                    }
                }
    
                function l() {
                    return i(d, f, h)
                }
    
                function c(e) {
                    var t;
                    return "object" == typeof e ? "r" in e ? (d = e.r, f = e.g, h = e.b) : "v" in e && o(e.h, e.s, e.v) : (t = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)[^\)]*\)/gi.exec(e)) ? (d = parseInt(t[1], 10), f = parseInt(t[2], 10), h = parseInt(t[3], 10)) : (t = /#([0-F]{2})([0-F]{2})([0-F]{2})/gi.exec(e)) ? (d = parseInt(t[1], 16), f = parseInt(t[2], 16), h = parseInt(t[3], 16)) : (t = /#([0-F])([0-F])([0-F])/gi.exec(e)) && (d = parseInt(t[1] + t[1], 16), f = parseInt(t[2] + t[2], 16), h = parseInt(t[3] + t[3], 16)), d = 0 > d ? 0 : d > 255 ? 255 : d, f = 0 > f ? 0 : f > 255 ? 255 : f, h = 0 > h ? 0 : h > 255 ? 255 : h, u
                }
                var u = this,
                    d = 0,
                    f = 0,
                    h = 0;
                e && c(e), u.toRgb = s, u.toHsv = l, u.toHex = a, u.parse = c
            }
            var t = Math.min,
                n = Math.max,
                r = Math.round;
            return e
        }), r(gt, [ke, ve, ce, mt], function(e, t, n, r) {
            return e.extend({
                Defaults: {
                    classes: "widget colorpicker"
                },
                init: function(e) {
                    this._super(e)
                },
                postRender: function() {
                    function e(e, t) {
                        var r = n.getPos(e),
                            i, o;
                        return i = t.pageX - r.x, o = t.pageY - r.y, i = Math.max(0, Math.min(i / e.clientWidth, 1)), o = Math.max(0, Math.min(o / e.clientHeight, 1)), {
                            x: i,
                            y: o
                        }
                    }
    
                    function i(e, t) {
                        var i = (360 - e.h) / 360;
                        n.css(d, {
                            top: 100 * i + "%"
                        }), t || n.css(h, {
                            left: e.s + "%",
                            top: 100 - e.v + "%"
                        }), f.style.background = new r({
                            s: 100,
                            v: 100,
                            h: e.h
                        }).toHex(), s.color().parse({
                            s: e.s,
                            v: e.v,
                            h: e.h
                        })
                    }
    
                    function o(t) {
                        var n;
                        n = e(f, t), c.s = 100 * n.x, c.v = 100 * (1 - n.y), i(c), s.fire("change")
                    }
    
                    function a(t) {
                        var n;
                        n = e(u, t), c = l.toHsv(), c.h = 360 * (1 - n.y), i(c, !0), s.fire("change")
                    }
                    var s = this,
                        l = s.color(),
                        c, u, d, f, h;
                    u = s.getEl("h"), d = s.getEl("hp"), f = s.getEl("sv"), h = s.getEl("svp"), s._repaint = function() {
                        c = l.toHsv(), i(c)
                    }, s._super(), s._svdraghelper = new t(s._id + "-sv", {
                        start: o,
                        drag: o
                    }), s._hdraghelper = new t(s._id + "-h", {
                        start: a,
                        drag: a
                    }), s._repaint()
                },
                rgb: function() {
                    return this.color().toRgb()
                },
                value: function(e) {
                    var t = this;
                    return arguments.length ? (t.color().parse(e), void(t._rendered && t._repaint())) : t.color().toHex()
                },
                color: function() {
                    return this._color || (this._color = new r), this._color
                },
                renderHtml: function() {
                    function e() {
                        var e, t, n = "",
                            i, a;
                        for (i = "filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=", a = o.split(","), e = 0, t = a.length - 1; t > e; e++) n += '<div class="' + r + 'colorpicker-h-chunk" style="height:' + 100 / t + "%;" + i + a[e] + ",endColorstr=" + a[e + 1] + ");-ms-" + i + a[e] + ",endColorstr=" + a[e + 1] + ')"></div>';
                        return n
                    }
                    var t = this,
                        n = t._id,
                        r = t.classPrefix,
                        i, o = "#ff0000,#ff0080,#ff00ff,#8000ff,#0000ff,#0080ff,#00ffff,#00ff80,#00ff00,#80ff00,#ffff00,#ff8000,#ff0000",
                        a = "background: -ms-linear-gradient(top," + o + ");background: linear-gradient(to bottom," + o + ");";
                    return i = '<div id="' + n + '-h" class="' + r + 'colorpicker-h" style="' + a + '">' + e() + '<div id="' + n + '-hp" class="' + r + 'colorpicker-h-marker"></div></div>', '<div id="' + n + '" class="' + t.classes + '"><div id="' + n + '-sv" class="' + r + 'colorpicker-sv"><div class="' + r + 'colorpicker-overlay1"><div class="' + r + 'colorpicker-overlay2"><div id="' + n + '-svp" class="' + r + 'colorpicker-selector1"><div class="' + r + 'colorpicker-selector2"></div></div></div></div></div>' + i + "</div>"
                }
            })
        }), r(vt, [ke], function(e) {
            return e.extend({
                init: function(e) {
                    var t = this;
                    e.delimiter || (e.delimiter = "\xbb"), t._super(e), t.classes.add("path"), t.canFocus = !0, t.on("click", function(e) {
                        var n, r = e.target;
                        (n = r.getAttribute("data-index")) && t.fire("select", {
                            value: t.row()[n],
                            index: n
                        })
                    }), t.row(t.settings.row)
                },
                focus: function() {
                    var e = this;
                    return e.getEl().firstChild.focus(), e
                },
                row: function(e) {
                    return arguments.length ? (this.state.set("row", e), this) : this.state.get("row")
                },
                renderHtml: function() {
                    var e = this;
                    return '<div id="' + e._id + '" class="' + e.classes + '">' + e._getDataPathHtml(e.state.get("row")) + "</div>"
                },
                bindStates: function() {
                    var e = this;
                    return e.state.on("change:row", function(t) {
                        e.innerHtml(e._getDataPathHtml(t.value))
                    }), e._super()
                },
                _getDataPathHtml: function(e) {
                    var t = this,
                        n = e || [],
                        r, i, o = "",
                        a = t.classPrefix;
                    for (r = 0, i = n.length; i > r; r++) o += (r > 0 ? '<div class="' + a + 'divider" aria-hidden="true"> ' + t.settings.delimiter + " </div>" : "") + '<div role="button" class="' + a + "path-item" + (r == i - 1 ? " " + a + "last" : "") + '" data-index="' + r + '" tabindex="-1" id="' + t._id + "-" + r + '" aria-level="' + r + '">' + n[r].name + "</div>";
                    return o || (o = '<div class="' + a + 'path-item">\xa0</div>'), o
                }
            })
        }), r(yt, [vt, Qe], function(e, t) {
            return e.extend({
                postRender: function() {
                    function e(e) {
                        if (1 === e.nodeType) {
                            if ("BR" == e.nodeName || e.getAttribute("data-mce-bogus")) return !0;
                            if ("bookmark" === e.getAttribute("data-mce-type")) return !0
                        }
                        return !1
                    }
                    var n = this,
                        r = t.activeEditor;
                    return r.settings.elementpath !== !1 && (n.on("select", function(e) {
                        r.focus(), r.selection.select(this.row()[e.index].element), r.nodeChanged()
                    }), r.on("nodeChange", function(t) {
                        for (var i = [], o = t.parents, a = o.length; a--;)
                            if (1 == o[a].nodeType && !e(o[a])) {
                                var s = r.fire("ResolveName", {
                                    name: o[a].nodeName.toLowerCase(),
                                    target: o[a]
                                });
                                if (s.isDefaultPrevented() || i.push({
                                        name: s.name,
                                        element: o[a]
                                    }), s.isPropagationStopped()) break
                            }
                        n.row(i)
                    })), n._super()
                }
            })
        }), r(bt, [ge], function(e) {
            return e.extend({
                Defaults: {
                    layout: "flex",
                    align: "center",
                    defaults: {
                        flex: 1
                    }
                },
                renderHtml: function() {
                    var e = this,
                        t = e._layout,
                        n = e.classPrefix;
                    return e.classes.add("formitem"), t.preRender(e), '<div id="' + e._id + '" class="' + e.classes + '" hidefocus="1" tabindex="-1">' + (e.settings.title ? '<div id="' + e._id + '-title" class="' + n + 'title">' + e.settings.title + "</div>" : "") + '<div id="' + e._id + '-body" class="' + e.bodyClasses + '">' + (e.settings.html || "") + t.renderHtml(e) + "</div></div>"
                }
            })
        }), r(Ct, [ge, bt, m], function(e, t, n) {
            return e.extend({
                Defaults: {
                    containerCls: "form",
                    layout: "flex",
                    direction: "column",
                    align: "stretch",
                    flex: 1,
                    padding: 20,
                    labelGap: 30,
                    spacing: 10,
                    callbacks: {
                        submit: function() {
                            this.submit()
                        }
                    }
                },
                preRender: function() {
                    var e = this,
                        r = e.items();
                    e.settings.formItemDefaults || (e.settings.formItemDefaults = {
                        layout: "flex",
                        autoResize: "overflow",
                        defaults: {
                            flex: 1
                        }
                    }), r.each(function(r) {
                        var i, o = r.settings.label;
                        o && (i = new t(n.extend({
                            items: {
                                type: "label",
                                id: r._id + "-l",
                                text: o,
                                flex: 0,
                                forId: r._id,
                                disabled: r.disabled()
                            }
                        }, e.settings.formItemDefaults)), i.type = "formitem", r.aria("labelledby", r._id + "-l"), "undefined" == typeof r.settings.flex && (r.settings.flex = 1), e.replace(r, i), i.add(r))
                    })
                },
                submit: function() {
                    return this.fire("submit", {
                        data: this.toJSON()
                    })
                },
                postRender: function() {
                    var e = this;
                    e._super(), e.fromJSON(e.settings.data)
                },
                bindStates: function() {
                    function e() {
                        var e = 0,
                            n = [],
                            r, i, o;
                        if (t.settings.labelGapCalc !== !1)
                            for (o = "children" == t.settings.labelGapCalc ? t.find("formitem") : t.items(), o.filter("formitem").each(function(t) {
                                    var r = t.items()[0],
                                        i = r.getEl().clientWidth;
                                    e = i > e ? i : e, n.push(r)
                                }), i = t.settings.labelGap || 0, r = n.length; r--;) n[r].settings.minWidth = e + i
                    }
                    var t = this;
                    t._super(), t.on("show", e), e()
                }
            })
        }), r(xt, [Ct], function(e) {
            return e.extend({
                Defaults: {
                    containerCls: "fieldset",
                    layout: "flex",
                    direction: "column",
                    align: "stretch",
                    flex: 1,
                    padding: "25 15 5 15",
                    labelGap: 30,
                    spacing: 10,
                    border: 1
                },
                renderHtml: function() {
                    var e = this,
                        t = e._layout,
                        n = e.classPrefix;
                    return e.preRender(), t.preRender(e), '<fieldset id="' + e._id + '" class="' + e.classes + '" hidefocus="1" tabindex="-1">' + (e.settings.title ? '<legend id="' + e._id + '-title" class="' + n + 'fieldset-title">' + e.settings.title + "</legend>" : "") + '<div id="' + e._id + '-body" class="' + e.bodyClasses + '">' + (e.settings.html || "") + t.renderHtml(e) + "</div></fieldset>"
                }
            })
        }), r(wt, [dt, m], function(e, t) {
            return e.extend({
                init: function(e) {
                    var n = this,
                        r = tinymce.activeEditor,
                        i = r.settings,
                        o, a, s;
                    e.spellcheck = !1, s = i.file_picker_types || i.file_browser_callback_types, s && (s = t.makeMap(s, /[, ]/)), (!s || s[e.filetype]) && (a = i.file_picker_callback, !a || s && !s[e.filetype] ? (a = i.file_browser_callback, !a || s && !s[e.filetype] || (o = function() {
                        a(n.getEl("inp").id, n.value(), e.filetype, window)
                    })) : o = function() {
                        var i = n.fire("beforecall").meta;
                        i = t.extend({
                            filetype: e.filetype
                        }, i), a.call(r, function(e, t) {
                            n.value(e).fire("change", {
                                meta: t
                            })
                        }, n.value(), i)
                    }), o && (e.icon = "browse", e.onaction = o), n._super(e)
                }
            })
        }), r(Et, [st], function(e) {
            return e.extend({
                recalc: function(e) {
                    var t = e.layoutRect(),
                        n = e.paddingBox;
                    e.items().filter(":visible").each(function(e) {
                        e.layoutRect({
                            x: n.left,
                            y: n.top,
                            w: t.innerW - n.right - n.left,
                            h: t.innerH - n.top - n.bottom
                        }), e.recalc && e.recalc()
                    })
                }
            })
        }), r(Nt, [st], function(e) {
            return e.extend({
                recalc: function(e) {
                    var t, n, r, i, o, a, s, l, c, u, d, f, h, p, m, g, v = [],
                        y, b, C, x, w, E, N, _, S, k, T, R, A, B, D, M, L, P, H, O, I, F, z = Math.max,
                        W = Math.min;
                    for (r = e.items().filter(":visible"), i = e.layoutRect(), o = e.paddingBox, a = e.settings, f = e.isRtl() ? a.direction || "row-reversed" : a.direction, s = a.align, l = e.isRtl() ? a.pack || "end" : a.pack, c = a.spacing || 0, ("row-reversed" == f || "column-reverse" == f) && (r = r.set(r.toArray().reverse()), f = f.split("-")[0]), "column" == f ? (S = "y", N = "h", _ = "minH", k = "maxH", R = "innerH", T = "top", A = "deltaH", B = "contentH", H = "left", L = "w", D = "x", M = "innerW", P = "minW", O = "right", I = "deltaW", F = "contentW") : (S = "x", N = "w", _ = "minW", k = "maxW", R = "innerW", T = "left", A = "deltaW", B = "contentW", H = "top", L = "h", D = "y", M = "innerH", P = "minH", O = "bottom", I = "deltaH", F = "contentH"), d = i[R] - o[T] - o[T], E = u = 0, t = 0, n = r.length; n > t; t++) h = r[t], p = h.layoutRect(), m = h.settings, g = m.flex, d -= n - 1 > t ? c : 0, g > 0 && (u += g, p[k] && v.push(h), p.flex = g), d -= p[_], y = o[H] + p[P] + o[O], y > E && (E = y);
                    if (x = {}, 0 > d ? x[_] = i[_] - d + i[A] : x[_] = i[R] - d + i[A], x[P] = E + i[I], x[B] = i[R] - d, x[F] = E, x.minW = W(x.minW, i.maxW), x.minH = W(x.minH, i.maxH), x.minW = z(x.minW, i.startMinWidth), x.minH = z(x.minH, i.startMinHeight), !i.autoResize || x.minW == i.minW && x.minH == i.minH) {
                        for (C = d / u, t = 0, n = v.length; n > t; t++) h = v[t], p = h.layoutRect(), b = p[k], y = p[_] + p.flex * C, y > b ? (d -= p[k] - p[_], u -= p.flex, p.flex = 0, p.maxFlexSize = b) : p.maxFlexSize = 0;
                        for (C = d / u, w = o[T], x = {}, 0 === u && ("end" == l ? w = d + o[T] : "center" == l ? (w = Math.round(i[R] / 2 - (i[R] - d) / 2) + o[T], 0 > w && (w = o[T])) : "justify" == l && (w = o[T], c = Math.floor(d / (r.length - 1)))), x[D] = o[H], t = 0, n = r.length; n > t; t++) h = r[t], p = h.layoutRect(), y = p.maxFlexSize || p[_], "center" === s ? x[D] = Math.round(i[M] / 2 - p[L] / 2) : "stretch" === s ? (x[L] = z(p[P] || 0, i[M] - o[H] - o[O]), x[D] = o[H]) : "end" === s && (x[D] = i[M] - p[L] - o.top), p.flex > 0 && (y += p.flex * C), x[N] = y, x[S] = w, h.layoutRect(x), h.recalc && h.recalc(), w += y + c
                    } else if (x.w = x.minW, x.h = x.minH, e.layoutRect(x), this.recalc(e), null === e._lastRect) {
                        var V = e.parent();
                        V && (V._lastRect = null, V.recalc())
                    }
                }
            })
        }), r(_t, [at], function(e) {
            return e.extend({
                Defaults: {
                    containerClass: "flow-layout",
                    controlClass: "flow-layout-item",
                    endClass: "break"
                },
                recalc: function(e) {
                    e.items().filter(":visible").each(function(e) {
                        e.recalc && e.recalc()
                    })
                },
                isNative: function() {
                    return !0
                }
            })
        }), r(St, [he, ke, we, m, Qe, h], function(e, t, n, r, i, o) {
            function a(e) {
                function t(t, n) {
                    return function() {
                        var r = this;
                        e.on("nodeChange", function(i) {
                            var o = e.formatter,
                                a = null;
                            s(i.parents, function(e) {
                                return s(t, function(t) {
                                    return n ? o.matchNode(e, n, {
                                        value: t.value
                                    }) && (a = t.value) : o.matchNode(e, t.value) && (a = t.value), a ? !1 : void 0
                                }), a ? !1 : void 0
                            }), r.value(a)
                        })
                    }
                }
    
                function r(e) {
                    e = e.replace(/;$/, "").split(";");
                    for (var t = e.length; t--;) e[t] = e[t].split("=");
                    return e
                }
    
                function i() {
                    function t(e) {
                        var n = [];
                        if (e) return s(e, function(e) {
                            var o = {
                                text: e.title,
                                icon: e.icon
                            };
                            if (e.items) o.menu = t(e.items);
                            else {
                                var a = e.format || "custom" + r++;
                                e.format || (e.name = a, i.push(e)), o.format = a, o.cmd = e.cmd
                            }
                            n.push(o)
                        }), n
                    }
    
                    function n() {
                        var n;
                        return n = t(e.settings.style_formats_merge ? e.settings.style_formats ? o.concat(e.settings.style_formats) : o : e.settings.style_formats || o)
                    }
                    var r = 0,
                        i = [],
                        o = [{
                            title: "Headings",
                            items: [{
                                title: "Heading 1",
                                format: "h1"
                            }, {
                                title: "Heading 2",
                                format: "h2"
                            }, {
                                title: "Heading 3",
                                format: "h3"
                            }, {
                                title: "Heading 4",
                                format: "h4"
                            }, {
                                title: "Heading 5",
                                format: "h5"
                            }, {
                                title: "Heading 6",
                                format: "h6"
                            }]
                        }, {
                            title: "Inline",
                            items: [{
                                title: "Bold",
                                icon: "bold",
                                format: "bold"
                            }, {
                                title: "Italic",
                                icon: "italic",
                                format: "italic"
                            }, {
                                title: "Underline",
                                icon: "underline",
                                format: "underline"
                            }, {
                                title: "Strikethrough",
                                icon: "strikethrough",
                                format: "strikethrough"
                            }, {
                                title: "Superscript",
                                icon: "superscript",
                                format: "superscript"
                            }, {
                                title: "Subscript",
                                icon: "subscript",
                                format: "subscript"
                            }, {
                                title: "Code",
                                icon: "code",
                                format: "code"
                            }]
                        }, {
                            title: "Blocks",
                            items: [{
                                title: "Paragraph",
                                format: "p"
                            }, {
                                title: "Blockquote",
                                format: "blockquote"
                            }, {
                                title: "Div",
                                format: "div"
                            }, {
                                title: "Pre",
                                format: "pre"
                            }]
                        }, {
                            title: "Alignment",
                            items: [{
                                title: "Left",
                                icon: "alignleft",
                                format: "alignleft"
                            }, {
                                title: "Center",
                                icon: "aligncenter",
                                format: "aligncenter"
                            }, {
                                title: "Right",
                                icon: "alignright",
                                format: "alignright"
                            }, {
                                title: "Justify",
                                icon: "alignjustify",
                                format: "alignjustify"
                            }]
                        }];
                    return e.on("init", function() {
                        s(i, function(t) {
                            e.formatter.register(t.name, t)
                        })
                    }), {
                        type: "menu",
                        items: n(),
                        onPostRender: function(t) {
                            e.fire("renderFormatsMenu", {
                                control: t.control
                            })
                        },
                        itemDefaults: {
                            preview: !0,
                            textStyle: function() {
                                return this.settings.format ? e.formatter.getCssText(this.settings.format) : void 0
                            },
                            onPostRender: function() {
                                var t = this;
                                t.parent().on("show", function() {
                                    var n, r;
                                    n = t.settings.format, n && (t.disabled(!e.formatter.canApply(n)), t.active(e.formatter.match(n))), r = t.settings.cmd, r && t.active(e.queryCommandState(r))
                                })
                            },
                            onclick: function() {
                                this.settings.format && c(this.settings.format), this.settings.cmd && e.execCommand(this.settings.cmd)
                            }
                        }
                    }
                }
    
                function o(t) {
                    return function() {
                        var n = this;
                        e.formatter ? e.formatter.formatChanged(t, function(e) {
                            n.active(e)
                        }) : e.on("init", function() {
                            e.formatter.formatChanged(t, function(e) {
                                n.active(e)
                            })
                        })
                    }
                }
    
                function a(t) {
                    return function() {
                        function n() {
                            return e.undoManager ? e.undoManager[t]() : !1
                        }
                        var r = this;
                        t = "redo" == t ? "hasRedo" : "hasUndo", r.disabled(!n()), e.on("Undo Redo AddUndo TypingUndo ClearUndos SwitchMode", function() {
                            r.disabled(e.readonly || !n())
                        })
                    }
                }
    
                function l() {
                    var t = this;
                    e.on("VisualAid", function(e) {
                        t.active(e.hasVisual)
                    }), t.active(e.hasVisual)
                }
    
                function c(t) {
                    t.control && (t = t.control.value()), t && e.execCommand("mceToggleFormat", !1, t)
                }
                var u;
                u = i(), s({
                    bold: "Bold",
                    italic: "Italic",
                    underline: "Underline",
                    strikethrough: "Strikethrough",
                    subscript: "Subscript",
                    superscript: "Superscript"
                }, function(t, n) {
                    e.addButton(n, {
                        tooltip: t,
                        onPostRender: o(n),
                        onclick: function() {
                            c(n)
                        }
                    })
                }), s({
                    outdent: ["Decrease indent", "Outdent"],
                    indent: ["Increase indent", "Indent"],
                    cut: ["Cut", "Cut"],
                    copy: ["Copy", "Copy"],
                    paste: ["Paste", "Paste"],
                    help: ["Help", "mceHelp"],
                    selectall: ["Select all", "SelectAll"],
                    removeformat: ["Clear formatting", "RemoveFormat"],
                    visualaid: ["Visual aids", "mceToggleVisualAid"],
                    newdocument: ["New document", "mceNewDocument"]
                }, function(t, n) {
                    e.addButton(n, {
                        tooltip: t[0],
                        cmd: t[1]
                    })
                }), s({
                    blockquote: ["Blockquote", "mceBlockQuote"],
                    numlist: ["Numbered list", "InsertOrderedList"],
                    bullist: ["Bullet list", "InsertUnorderedList"],
                    subscript: ["Subscript", "Subscript"],
                    superscript: ["Superscript", "Superscript"],
                    alignleft: ["Align left", "JustifyLeft"],
                    aligncenter: ["Align center", "JustifyCenter"],
                    alignright: ["Align right", "JustifyRight"],
                    alignjustify: ["Justify", "JustifyFull"],
                    alignnone: ["No alignment", "JustifyNone"]
                }, function(t, n) {
                    e.addButton(n, {
                        tooltip: t[0],
                        cmd: t[1],
                        onPostRender: o(n)
                    })
                }), e.addButton("undo", {
                    tooltip: "Undo",
                    onPostRender: a("undo"),
                    cmd: "undo"
                }), e.addButton("redo", {
                    tooltip: "Redo",
                    onPostRender: a("redo"),
                    cmd: "redo"
                }), e.addMenuItem("newdocument", {
                    text: "New document",
                    icon: "newdocument",
                    cmd: "mceNewDocument"
                }), e.addMenuItem("undo", {
                    text: "Undo",
                    icon: "undo",
                    shortcut: "Meta+Z",
                    onPostRender: a("undo"),
                    cmd: "undo"
                }), e.addMenuItem("redo", {
                    text: "Redo",
                    icon: "redo",
                    shortcut: "Meta+Y",
                    onPostRender: a("redo"),
                    cmd: "redo"
                }), e.addMenuItem("visualaid", {
                    text: "Visual aids",
                    selectable: !0,
                    onPostRender: l,
                    cmd: "mceToggleVisualAid"
                }), e.addButton("remove", {
                    tooltip: "Remove",
                    icon: "remove",
                    cmd: "Delete"
                }), s({
                    cut: ["Cut", "Cut", "Meta+X"],
                    copy: ["Copy", "Copy", "Meta+C"],
                    paste: ["Paste", "Paste", "Meta+V"],
                    selectall: ["Select all", "SelectAll", "Meta+A"],
                    bold: ["Bold", "Bold", "Meta+B"],
                    italic: ["Italic", "Italic", "Meta+I"],
                    underline: ["Underline", "Underline"],
                    strikethrough: ["Strikethrough", "Strikethrough"],
                    subscript: ["Subscript", "Subscript"],
                    superscript: ["Superscript", "Superscript"],
                    removeformat: ["Clear formatting", "RemoveFormat"]
                }, function(t, n) {
                    e.addMenuItem(n, {
                        text: t[0],
                        icon: n,
                        shortcut: t[2],
                        cmd: t[1]
                    })
                }), e.on("mousedown", function() {
                    n.hideAll()
                }), e.addButton("styleselect", {
                    type: "menubutton",
                    text: "Formats",
                    menu: u
                }), e.addButton("formatselect", function() {
                    var n = [],
                        i = r(e.settings.block_formats || "Paragraph=p;Heading 1=h1;Heading 2=h2;Heading 3=h3;Heading 4=h4;Heading 5=h5;Heading 6=h6;Preformatted=pre");
                    return s(i, function(t) {
                        n.push({
                            text: t[0],
                            value: t[1],
                            textStyle: function() {
                                return e.formatter.getCssText(t[1])
                            }
                        })
                    }), {
                        type: "listbox",
                        text: i[0][0],
                        values: n,
                        fixedWidth: !0,
                        onselect: c,
                        onPostRender: t(n)
                    }
                }), e.addButton("fontselect", function() {
                    var n = "Andale Mono=andale mono,monospace;Arial=arial,helvetica,sans-serif;Arial Black=arial black,sans-serif;Book Antiqua=book antiqua,palatino,serif;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier,monospace;Georgia=georgia,palatino,serif;Helvetica=helvetica,arial,sans-serif;Impact=impact,sans-serif;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco,monospace;Times New Roman=times new roman,times,serif;Trebuchet MS=trebuchet ms,geneva,sans-serif;Verdana=verdana,geneva,sans-serif;Webdings=webdings;Wingdings=wingdings,zapf dingbats",
                        i = [],
                        o = r(e.settings.font_formats || n);
                    return s(o, function(e) {
                        i.push({
                            text: {
                                raw: e[0]
                            },
                            value: e[1],
                            textStyle: -1 == e[1].indexOf("dings") ? "font-family:" + e[1] : ""
                        })
                    }), {
                        type: "listbox",
                        text: "Font Family",
                        tooltip: "Font Family",
                        values: i,
                        fixedWidth: !0,
                        onPostRender: t(i, "fontname"),
                        onselect: function(t) {
                            t.control.settings.value && e.execCommand("FontName", !1, t.control.settings.value)
                        }
                    }
                }), e.addButton("fontsizeselect", function() {
                    var n = [],
                        r = "8pt 10pt 12pt 14pt 18pt 24pt 36pt",
                        i = e.settings.fontsize_formats || r;
                    return s(i.split(" "), function(e) {
                        var t = e,
                            r = e,
                            i = e.split("=");
                        i.length > 1 && (t = i[0], r = i[1]), n.push({
                            text: t,
                            value: r
                        })
                    }), {
                        type: "listbox",
                        text: "Font Sizes",
                        tooltip: "Font Sizes",
                        values: n,
                        fixedWidth: !0,
                        onPostRender: t(n, "fontsize"),
                        onclick: function(t) {
                            t.control.settings.value && e.execCommand("FontSize", !1, t.control.settings.value)
                        }
                    }
                }), e.addMenuItem("formats", {
                    text: "Formats",
                    menu: u
                })
            }
            var s = r.each;
            i.on("AddEditor", function(t) {
                t.editor.rtl && (e.rtl = !0), a(t.editor)
            }), e.translate = function(e) {
                return i.translate(e)
            }, t.tooltips = !o.iOS
        }), r(kt, [st], function(e) {
            return e.extend({
                recalc: function(e) {
                    var t, n, r, i, o, a, s, l, c, u, d, f, h, p, m, g, v, y, b, C, x, w, E, N = [],
                        _ = [],
                        S, k, T, R, A, B;
                    t = e.settings, i = e.items().filter(":visible"), o = e.layoutRect(), r = t.columns || Math.ceil(Math.sqrt(i.length)), n = Math.ceil(i.length / r), y = t.spacingH || t.spacing || 0, b = t.spacingV || t.spacing || 0, C = t.alignH || t.align, x = t.alignV || t.align, g = e.paddingBox, A = "reverseRows" in t ? t.reverseRows : e.isRtl(), C && "string" == typeof C && (C = [C]), x && "string" == typeof x && (x = [x]);
                    for (d = 0; r > d; d++) N.push(0);
                    for (f = 0; n > f; f++) _.push(0);
                    for (f = 0; n > f; f++)
                        for (d = 0; r > d && (u = i[f * r + d], u); d++) c = u.layoutRect(), S = c.minW, k = c.minH, N[d] = S > N[d] ? S : N[d], _[f] = k > _[f] ? k : _[f];
                    for (T = o.innerW - g.left - g.right, w = 0, d = 0; r > d; d++) w += N[d] + (d > 0 ? y : 0), T -= (d > 0 ? y : 0) + N[d];
                    for (R = o.innerH - g.top - g.bottom, E = 0, f = 0; n > f; f++) E += _[f] + (f > 0 ? b : 0), R -= (f > 0 ? b : 0) + _[f];
                    if (w += g.left + g.right, E += g.top + g.bottom, l = {}, l.minW = w + (o.w - o.innerW), l.minH = E + (o.h - o.innerH), l.contentW = l.minW - o.deltaW, l.contentH = l.minH - o.deltaH, l.minW = Math.min(l.minW, o.maxW), l.minH = Math.min(l.minH, o.maxH), l.minW = Math.max(l.minW, o.startMinWidth), l.minH = Math.max(l.minH, o.startMinHeight), !o.autoResize || l.minW == o.minW && l.minH == o.minH) {
                        o.autoResize && (l = e.layoutRect(l), l.contentW = l.minW - o.deltaW, l.contentH = l.minH - o.deltaH);
                        var D;
                        D = "start" == t.packV ? 0 : R > 0 ? Math.floor(R / n) : 0;
                        var M = 0,
                            L = t.flexWidths;
                        if (L)
                            for (d = 0; d < L.length; d++) M += L[d];
                        else M = r;
                        var P = T / M;
                        for (d = 0; r > d; d++) N[d] += L ? L[d] * P : P;
                        for (p = g.top, f = 0; n > f; f++) {
                            for (h = g.left, s = _[f] + D, d = 0; r > d && (B = A ? f * r + r - 1 - d : f * r + d, u = i[B], u); d++) m = u.settings, c = u.layoutRect(), a = Math.max(N[d], c.startMinWidth), c.x = h, c.y = p, v = m.alignH || (C ? C[d] || C[0] : null), "center" == v ? c.x = h + a / 2 - c.w / 2 : "right" == v ? c.x = h + a - c.w : "stretch" == v && (c.w = a), v = m.alignV || (x ? x[d] || x[0] : null), "center" == v ? c.y = p + s / 2 - c.h / 2 : "bottom" == v ? c.y = p + s - c.h : "stretch" == v && (c.h = s), u.layoutRect(c), h += a + y, u.recalc && u.recalc();
                            p += s + b
                        }
                    } else if (l.w = l.minW, l.h = l.minH, e.layoutRect(l), this.recalc(e), null === e._lastRect) {
                        var H = e.parent();
                        H && (H._lastRect = null, H.recalc())
                    }
                }
            })
        }), r(Tt, [ke, u], function(e, t) {
            return e.extend({
                renderHtml: function() {
                    var e = this;
                    return e.classes.add("iframe"), e.canFocus = !1, '<iframe id="' + e._id + '" class="' + e.classes + '" tabindex="-1" src="' + (e.settings.url || "javascript:''") + '" frameborder="0"></iframe>'
                },
                src: function(e) {
                    this.getEl().src = e
                },
                html: function(e, n) {
                    var r = this,
                        i = this.getEl().contentWindow.document.body;
                    return i ? (i.innerHTML = e, n && n()) : t.setTimeout(function() {
                        r.html(e)
                    }), this
                }
            })
        }), r(Rt, [ke, ce], function(e, t) {
            return e.extend({
                init: function(e) {
                    var t = this;
                    t._super(e), t.classes.add("widget").add("label"), t.canFocus = !1, e.multiline && t.classes.add("autoscroll"), e.strong && t.classes.add("strong")
                },
                initLayoutRect: function() {
                    var e = this,
                        n = e._super();
                    if (e.settings.multiline) {
                        var r = t.getSize(e.getEl());
                        r.width > n.maxW && (n.minW = n.maxW, e.classes.add("multiline")), e.getEl().style.width = n.minW + "px", n.startMinH = n.h = n.minH = Math.min(n.maxH, t.getSize(e.getEl()).height)
                    }
                    return n
                },
                repaint: function() {
                    var e = this;
                    return e.settings.multiline || (e.getEl().style.lineHeight = e.layoutRect().h + "px"), e._super()
                },
                renderHtml: function() {
                    var e = this,
                        t = e.settings.forId;
                    return '<label id="' + e._id + '" class="' + e.classes + '"' + (t ? ' for="' + t + '"' : "") + ">" + e.encode(e.state.get("text")) + "</label>"
                },
                bindStates: function() {
                    var e = this;
                    return e.state.on("change:text", function(t) {
                        e.innerHtml(e.encode(t.value))
                    }), e._super()
                }
            })
        }), r(At, [ge], function(e) {
            return e.extend({
                Defaults: {
                    role: "toolbar",
                    layout: "flow"
                },
                init: function(e) {
                    var t = this;
                    t._super(e), t.classes.add("toolbar")
                },
                postRender: function() {
                    var e = this;
                    return e.items().each(function(e) {
                        e.classes.add("toolbar-item")
                    }), e._super()
                }
            })
        }), r(Bt, [At], function(e) {
            return e.extend({
                Defaults: {
                    role: "menubar",
                    containerCls: "menubar",
                    ariaRoot: !0,
                    defaults: {
                        type: "menubutton"
                    }
                }
            })
        }), r(Dt, [lt, pe, Bt], function(e, t, n) {
            function r(e, t) {
                for (; e;) {
                    if (t === e) return !0;
                    e = e.parentNode
                }
                return !1
            }
            var i = e.extend({
                init: function(e) {
                    var t = this;
                    t._renderOpen = !0, t._super(e), e = t.settings, t.classes.add("menubtn"), e.fixedWidth && t.classes.add("fixed-width"), t.aria("haspopup", !0), t.state.set("menu", e.menu || t.render())
                },
                showMenu: function() {
                    var e = this,
                        n;
                    return e.menu && e.menu.visible() ? e.hideMenu() : (e.menu || (n = e.state.get("menu") || [], n.length ? n = {
                        type: "menu",
                        items: n
                    } : n.type = n.type || "menu", n.renderTo ? e.menu = n.parent(e).show().renderTo() : e.menu = t.create(n).parent(e).renderTo(), e.fire("createmenu"), e.menu.reflow(), e.menu.on("cancel", function(t) {
                        t.control.parent() === e.menu && (t.stopPropagation(), e.focus(), e.hideMenu())
                    }), e.menu.on("select", function() {
                        e.focus()
                    }), e.menu.on("show hide", function(t) {
                        t.control == e.menu && e.activeMenu("show" == t.type), e.aria("expanded", "show" == t.type)
                    }).fire("show")), e.menu.show(), e.menu.layoutRect({
                        w: e.layoutRect().w
                    }), void e.menu.moveRel(e.getEl(), e.isRtl() ? ["br-tr", "tr-br"] : ["bl-tl", "tl-bl"]))
                },
                hideMenu: function() {
                    var e = this;
                    e.menu && (e.menu.items().each(function(e) {
                        e.hideMenu && e.hideMenu()
                    }), e.menu.hide())
                },
                activeMenu: function(e) {
                    this.classes.toggle("active", e)
                },
                renderHtml: function() {
                    var e = this,
                        t = e._id,
                        r = e.classPrefix,
                        i = e.settings.icon,
                        o, a = e.state.get("text"),
                        s = "";
                    return o = e.settings.image, o ? (i = "none", "string" != typeof o && (o = window.getSelection ? o[0] : o[1]), o = " style=\"background-image: url('" + o + "')\"") : o = "", a && (e.classes.add("btn-has-text"), s = '<span class="' + r + 'txt">' + e.encode(a) + "</span>"), i = e.settings.icon ? r + "ico " + r + "i-" + i : "", e.aria("role", e.parent() instanceof n ? "menuitem" : "button"), '<div id="' + t + '" class="' + e.classes + '" tabindex="-1" aria-labelledby="' + t + '"><button id="' + t + '-open" role="presentation" type="button" tabindex="-1">' + (i ? '<i class="' + i + '"' + o + "></i>" : "") + s + ' <i class="' + r + 'caret"></i></button></div>'
                },
                postRender: function() {
                    var e = this;
                    return e.on("click", function(t) {
                        t.control === e && r(t.target, e.getEl()) && (e.showMenu(), t.aria && e.menu.items()[0].focus())
                    }), e.on("mouseenter", function(t) {
                        var n = t.control,
                            r = e.parent(),
                            o;
                        n && r && n instanceof i && n.parent() == r && (r.items().filter("MenuButton").each(function(e) {
                            e.hideMenu && e != n && (e.menu && e.menu.visible() && (o = !0), e.hideMenu())
                        }), o && (n.focus(), n.showMenu()))
                    }), e._super()
                },
                bindStates: function() {
                    var e = this;
                    return e.state.on("change:menu", function() {
                        e.menu && e.menu.remove(), e.menu = null
                    }), e._super()
                },
                remove: function() {
                    this._super(), this.menu && this.menu.remove()
                }
            });
            return i
        }), r(Mt, [ke, pe, h], function(e, t, n) {
            return e.extend({
                Defaults: {
                    border: 0,
                    role: "menuitem"
                },
                init: function(e) {
                    var t = this,
                        n;
                    t._super(e), e = t.settings, t.classes.add("menu-item"), e.menu && t.classes.add("menu-item-expand"), e.preview && t.classes.add("menu-item-preview"), n = t.state.get("text"), ("-" === n || "|" === n) && (t.classes.add("menu-item-sep"), t.aria("role", "separator"),
                        t.state.set("text", "-")), e.selectable && (t.aria("role", "menuitemcheckbox"), t.classes.add("menu-item-checkbox"), e.icon = "selected"), e.preview || e.selectable || t.classes.add("menu-item-normal"), t.on("mousedown", function(e) {
                        e.preventDefault()
                    }), e.menu && !e.ariaHideMenu && t.aria("haspopup", !0)
                },
                hasMenus: function() {
                    return !!this.settings.menu
                },
                showMenu: function() {
                    var e = this,
                        n = e.settings,
                        r, i = e.parent();
                    if (i.items().each(function(t) {
                            t !== e && t.hideMenu()
                        }), n.menu) {
                        r = e.menu, r ? r.show() : (r = n.menu, r.length ? r = {
                            type: "menu",
                            items: r
                        } : r.type = r.type || "menu", i.settings.itemDefaults && (r.itemDefaults = i.settings.itemDefaults), r = e.menu = t.create(r).parent(e).renderTo(), r.reflow(), r.on("cancel", function(t) {
                            t.stopPropagation(), e.focus(), r.hide()
                        }), r.on("show hide", function(e) {
                            e.control.items().each(function(e) {
                                e.active(e.settings.selected)
                            })
                        }).fire("show"), r.on("hide", function(t) {
                            t.control === r && e.classes.remove("selected")
                        }), r.submenu = !0), r._parentMenu = i, r.classes.add("menu-sub");
                        var o = r.testMoveRel(e.getEl(), e.isRtl() ? ["tl-tr", "bl-br", "tr-tl", "br-bl"] : ["tr-tl", "br-bl", "tl-tr", "bl-br"]);
                        r.moveRel(e.getEl(), o), r.rel = o, o = "menu-sub-" + o, r.classes.remove(r._lastRel).add(o), r._lastRel = o, e.classes.add("selected"), e.aria("expanded", !0)
                    }
                },
                hideMenu: function() {
                    var e = this;
                    return e.menu && (e.menu.items().each(function(e) {
                        e.hideMenu && e.hideMenu()
                    }), e.menu.hide(), e.aria("expanded", !1)), e
                },
                renderHtml: function() {
                    function e(e) {
                        var t, r, i = {};
                        for (i = n.mac ? {
                                alt: "&#x2325;",
                                ctrl: "&#x2318;",
                                shift: "&#x21E7;",
                                meta: "&#x2318;"
                            } : {
                                meta: "Ctrl"
                            }, e = e.split("+"), t = 0; t < e.length; t++) r = i[e[t].toLowerCase()], r && (e[t] = r);
                        return e.join("+")
                    }
                    var t = this,
                        r = t._id,
                        i = t.settings,
                        o = t.classPrefix,
                        a = t.encode(t.state.get("text")),
                        s = t.settings.icon,
                        l = "",
                        c = i.shortcut;
                    return s && t.parent().classes.add("menu-has-icons"), i.image && (l = " style=\"background-image: url('" + i.image + "')\""), c && (c = e(c)), s = o + "ico " + o + "i-" + (t.settings.icon || "none"), '<div id="' + r + '" class="' + t.classes + '" tabindex="-1">' + ("-" !== a ? '<i class="' + s + '"' + l + "></i>\xa0" : "") + ("-" !== a ? '<span id="' + r + '-text" class="' + o + 'text">' + a + "</span>" : "") + (c ? '<div id="' + r + '-shortcut" class="' + o + 'menu-shortcut">' + c + "</div>" : "") + (i.menu ? '<div class="' + o + 'caret"></div>' : "") + "</div>"
                },
                postRender: function() {
                    var e = this,
                        t = e.settings,
                        n = t.textStyle;
                    if ("function" == typeof n && (n = n.call(this)), n) {
                        var r = e.getEl("text");
                        r && r.setAttribute("style", n)
                    }
                    return e.on("mouseenter click", function(n) {
                        n.control === e && (t.menu || "click" !== n.type ? (e.showMenu(), n.aria && e.menu.focus(!0)) : (e.fire("select"), e.parent().hideAll()))
                    }), e._super(), e
                },
                active: function(e) {
                    return "undefined" != typeof e && this.aria("checked", e), this._super(e)
                },
                remove: function() {
                    this._super(), this.menu && this.menu.remove()
                }
            })
        }), r(Lt, [we, Mt, m], function(e, t, n) {
            return e.extend({
                Defaults: {
                    defaultType: "menuitem",
                    border: 1,
                    layout: "stack",
                    role: "application",
                    bodyRole: "menu",
                    ariaRoot: !0
                },
                init: function(e) {
                    var t = this;
                    if (e.autohide = !0, e.constrainToViewport = !0, e.itemDefaults)
                        for (var r = e.items, i = r.length; i--;) r[i] = n.extend({}, e.itemDefaults, r[i]);
                    t._super(e), t.classes.add("menu")
                },
                repaint: function() {
                    return this.classes.toggle("menu-align", !0), this._super(), this.getEl().style.height = "", this.getEl("body").style.height = "", this
                },
                cancel: function() {
                    var e = this;
                    e.hideAll(), e.fire("select")
                },
                hideAll: function() {
                    var e = this;
                    return this.find("menuitem").exec("hideMenu"), e._super()
                },
                preRender: function() {
                    var e = this;
                    return e.items().each(function(t) {
                        var n = t.settings;
                        return n.icon || n.image || n.selectable ? (e._hasIcons = !0, !1) : void 0
                    }), e._super()
                }
            })
        }), r(Pt, [Dt, Lt], function(e, t) {
            return e.extend({
                init: function(e) {
                    function t(r) {
                        for (var a = 0; a < r.length; a++) {
                            if (i = r[a].selected || e.value === r[a].value) return o = o || r[a].text, n.state.set("value", r[a].value), !0;
                            if (r[a].menu && t(r[a].menu)) return !0
                        }
                    }
                    var n = this,
                        r, i, o, a;
                    n._super(e), e = n.settings, n._values = r = e.values, r && ("undefined" != typeof e.value && t(r), !i && r.length > 0 && (o = r[0].text, n.state.set("value", r[0].value)), n.state.set("menu", r)), n.state.set("text", e.text || o), n.classes.add("listbox"), n.on("select", function(t) {
                        var r = t.control;
                        a && (t.lastControl = a), e.multiple ? r.active(!r.active()) : n.value(t.control.value()), a = r
                    })
                },
                bindStates: function() {
                    function e(e, n) {
                        e instanceof t && e.items().each(function(e) {
                            e.hasMenus() || e.active(e.value() === n)
                        })
                    }
    
                    function n(e, t) {
                        var r;
                        if (e)
                            for (var i = 0; i < e.length; i++) {
                                if (e[i].value === t) return e[i];
                                if (e[i].menu && (r = n(e[i].menu, t))) return r
                            }
                    }
                    var r = this;
                    return r.on("show", function(t) {
                        e(t.control, r.value())
                    }), r.state.on("change:value", function(e) {
                        var t = n(r.state.get("menu"), e.value);
                        t ? r.text(t.text) : r.text(r.settings.text)
                    }), r._super()
                }
            })
        }), r(Ht, [ut], function(e) {
            return e.extend({
                Defaults: {
                    classes: "radio",
                    role: "radio"
                }
            })
        }), r(Ot, [ke, ve], function(e, t) {
            return e.extend({
                renderHtml: function() {
                    var e = this,
                        t = e.classPrefix;
                    return e.classes.add("resizehandle"), "both" == e.settings.direction && e.classes.add("resizehandle-both"), e.canFocus = !1, '<div id="' + e._id + '" class="' + e.classes + '"><i class="' + t + "ico " + t + 'i-resize"></i></div>'
                },
                postRender: function() {
                    var e = this;
                    e._super(), e.resizeDragHelper = new t(this._id, {
                        start: function() {
                            e.fire("ResizeStart")
                        },
                        drag: function(t) {
                            "both" != e.settings.direction && (t.deltaX = 0), e.fire("Resize", t)
                        },
                        stop: function() {
                            e.fire("ResizeEnd")
                        }
                    })
                },
                remove: function() {
                    return this.resizeDragHelper && this.resizeDragHelper.destroy(), this._super()
                }
            })
        }), r(It, [ke], function(e) {
            function t(e) {
                var t = "";
                if (e)
                    for (var n = 0; n < e.length; n++) t += '<option value="' + e[n] + '">' + e[n] + "</option>";
                return t
            }
            return e.extend({
                Defaults: {
                    classes: "selectbox",
                    role: "selectbox",
                    options: []
                },
                init: function(e) {
                    var t = this;
                    t._super(e), t.settings.size && (t.size = t.settings.size), t.settings.options && (t._options = t.settings.options)
                },
                options: function(e) {
                    return arguments.length ? (this.state.set("options", e), this) : this.state.get("options")
                },
                renderHtml: function() {
                    var e = this,
                        n, r = "";
                    return n = t(e._options), e.size && (r = ' size = "' + e.size + '"'), '<select id="' + e._id + '" class="' + e.classes + '"' + r + ">" + n + "</select>"
                },
                bindStates: function() {
                    var e = this;
                    return e.state.on("change:options", function(n) {
                        e.getEl().innerHTML = t(n.value)
                    }), e._super()
                }
            })
        }), r(Ft, [ke, ve, ce], function(e, t, n) {
            function r(e, t, n) {
                return t > e && (e = t), e > n && (e = n), e
            }
    
            function i(e, t) {
                var r, i, o, a, s;
                "v" == e.settings.orientation ? (a = "top", o = "height", i = "h") : (a = "left", o = "width", i = "w"), r = (e.layoutRect()[i] || 100) - n.getSize(e.getEl("handle"))[o], s = r * ((t - e._minValue) / (e._maxValue - e._minValue)) + "px", e.getEl("handle").style[a] = s, e.getEl("handle").style.height = e.layoutRect().h + "px"
            }
            return e.extend({
                init: function(e) {
                    var t = this;
                    e.previewFilter || (e.previewFilter = function(e) {
                        return Math.round(100 * e) / 100
                    }), t._super(e), t.classes.add("slider"), "v" == e.orientation && t.classes.add("vertical"), t._minValue = e.minValue || 0, t._maxValue = e.maxValue || 100, t._initValue = t.state.get("value")
                },
                renderHtml: function() {
                    var e = this,
                        t = e._id,
                        n = e.classPrefix;
                    return '<div id="' + t + '" class="' + e.classes + '"><div id="' + t + '-handle" class="' + n + 'slider-handle"></div></div>'
                },
                reset: function() {
                    this.value(this._initValue).repaint()
                },
                postRender: function() {
                    var e = this,
                        i, o, a = 0,
                        s, l, c, u, d, f, h, p;
                    l = e._minValue, c = e._maxValue, s = e.value(), "v" == e.settings.orientation ? (d = "screenY", f = "top", h = "height", p = "h") : (d = "screenX", f = "left", h = "width", p = "w"), e._super(), e._dragHelper = new t(e._id, {
                        handle: e._id + "-handle",
                        start: function(t) {
                            i = t[d], o = parseInt(e.getEl("handle").style[f], 10), u = (e.layoutRect()[p] || 100) - n.getSize(e.getEl("handle"))[h], e.fire("dragstart", {
                                value: s
                            })
                        },
                        drag: function(t) {
                            var n = t[d] - i,
                                h = e.getEl("handle");
                            a = r(o + n, 0, u), h.style[f] = a + "px", s = l + a / u * (c - l), e.value(s), e.tooltip().text("" + e.settings.previewFilter(s)).show().moveRel(h, "bc tc"), e.fire("drag", {
                                value: s
                            })
                        },
                        stop: function() {
                            e.tooltip().hide(), e.fire("dragend", {
                                value: s
                            })
                        }
                    })
                },
                repaint: function() {
                    this._super(), i(this, this.value())
                },
                bindStates: function() {
                    var e = this;
                    return e.state.on("change:value", function(t) {
                        i(e, t.value)
                    }), e._super()
                }
            })
        }), r(zt, [ke], function(e) {
            return e.extend({
                renderHtml: function() {
                    var e = this;
                    return e.classes.add("spacer"), e.canFocus = !1, '<div id="' + e._id + '" class="' + e.classes + '"></div>'
                }
            })
        }), r(Wt, [Dt, ce, g], function(e, t, n) {
            return e.extend({
                Defaults: {
                    classes: "widget btn splitbtn",
                    role: "button"
                },
                repaint: function() {
                    var e = this,
                        r = e.getEl(),
                        i = e.layoutRect(),
                        o, a;
                    return e._super(), o = r.firstChild, a = r.lastChild, n(o).css({
                        width: i.w - t.getSize(a).width,
                        height: i.h - 2
                    }), n(a).css({
                        height: i.h - 2
                    }), e
                },
                activeMenu: function(e) {
                    var t = this;
                    n(t.getEl().lastChild).toggleClass(t.classPrefix + "active", e)
                },
                renderHtml: function() {
                    var e = this,
                        t = e._id,
                        n = e.classPrefix,
                        r, i = e.state.get("icon"),
                        o = e.state.get("text"),
                        a = "";
                    return r = e.settings.image, r ? (i = "none", "string" != typeof r && (r = window.getSelection ? r[0] : r[1]), r = " style=\"background-image: url('" + r + "')\"") : r = "", i = e.settings.icon ? n + "ico " + n + "i-" + i : "", o && (e.classes.add("btn-has-text"), a = '<span class="' + n + 'txt">' + e.encode(o) + "</span>"), '<div id="' + t + '" class="' + e.classes + '" role="button" tabindex="-1"><button type="button" hidefocus="1" tabindex="-1">' + (i ? '<i class="' + i + '"' + r + "></i>" : "") + a + '</button><button type="button" class="' + n + 'open" hidefocus="1" tabindex="-1">' + (e._menuBtnText ? (i ? "\xa0" : "") + e._menuBtnText : "") + ' <i class="' + n + 'caret"></i></button></div>'
                },
                postRender: function() {
                    var e = this,
                        t = e.settings.onclick;
                    return e.on("click", function(e) {
                        var n = e.target;
                        if (e.control == this)
                            for (; n;) {
                                if (e.aria && "down" != e.aria.key || "BUTTON" == n.nodeName && -1 == n.className.indexOf("open")) return e.stopImmediatePropagation(), void(t && t.call(this, e));
                                n = n.parentNode
                            }
                    }), delete e.settings.onclick, e._super()
                }
            })
        }), r(Vt, [_t], function(e) {
            return e.extend({
                Defaults: {
                    containerClass: "stack-layout",
                    controlClass: "stack-layout-item",
                    endClass: "break"
                },
                isNative: function() {
                    return !0
                }
            })
        }), r(Ut, [be, g, ce], function(e, t, n) {
            return e.extend({
                Defaults: {
                    layout: "absolute",
                    defaults: {
                        type: "panel"
                    }
                },
                activateTab: function(e) {
                    var n;
                    this.activeTabId && (n = this.getEl(this.activeTabId), t(n).removeClass(this.classPrefix + "active"), n.setAttribute("aria-selected", "false")), this.activeTabId = "t" + e, n = this.getEl("t" + e), n.setAttribute("aria-selected", "true"), t(n).addClass(this.classPrefix + "active"), this.items()[e].show().fire("showtab"), this.reflow(), this.items().each(function(t, n) {
                        e != n && t.hide()
                    })
                },
                renderHtml: function() {
                    var e = this,
                        t = e._layout,
                        n = "",
                        r = e.classPrefix;
                    return e.preRender(), t.preRender(e), e.items().each(function(t, i) {
                        var o = e._id + "-t" + i;
                        t.aria("role", "tabpanel"), t.aria("labelledby", o), n += '<div id="' + o + '" class="' + r + 'tab" unselectable="on" role="tab" aria-controls="' + t._id + '" aria-selected="false" tabIndex="-1">' + e.encode(t.settings.title) + "</div>"
                    }), '<div id="' + e._id + '" class="' + e.classes + '" hidefocus="1" tabindex="-1"><div id="' + e._id + '-head" class="' + r + 'tabs" role="tablist">' + n + '</div><div id="' + e._id + '-body" class="' + e.bodyClasses + '">' + t.renderHtml(e) + "</div></div>"
                },
                postRender: function() {
                    var e = this;
                    e._super(), e.settings.activeTab = e.settings.activeTab || 0, e.activateTab(e.settings.activeTab), this.on("click", function(t) {
                        var n = t.target.parentNode;
                        if (t.target.parentNode.id == e._id + "-head")
                            for (var r = n.childNodes.length; r--;) n.childNodes[r] == t.target && e.activateTab(r)
                    })
                },
                initLayoutRect: function() {
                    var e = this,
                        t, r, i;
                    r = n.getSize(e.getEl("head")).width, r = 0 > r ? 0 : r, i = 0, e.items().each(function(e) {
                        r = Math.max(r, e.layoutRect().minW), i = Math.max(i, e.layoutRect().minH)
                    }), e.items().each(function(e) {
                        e.settings.x = 0, e.settings.y = 0, e.settings.w = r, e.settings.h = i, e.layoutRect({
                            x: 0,
                            y: 0,
                            w: r,
                            h: i
                        })
                    });
                    var o = n.getSize(e.getEl("head")).height;
                    return e.settings.minWidth = r, e.settings.minHeight = i + o, t = e._super(), t.deltaH += o, t.innerH = t.h - t.deltaH, t
                }
            })
        }), r($t, [ke], function(e) {
            return e.extend({
                init: function(e) {
                    var t = this;
                    t._super(e), t.classes.add("textbox"), e.multiline ? t.classes.add("multiline") : (t.on("keydown", function(e) {
                        var n;
                        13 == e.keyCode && (e.preventDefault(), t.parents().reverse().each(function(e) {
                            return e.toJSON ? (n = e, !1) : void 0
                        }), t.fire("submit", {
                            data: n.toJSON()
                        }))
                    }), t.on("keyup", function(e) {
                        t.state.set("value", e.target.value)
                    }))
                },
                repaint: function() {
                    var e = this,
                        t, n, r, i, o = 0,
                        a;
                    t = e.getEl().style, n = e._layoutRect, a = e._lastRepaintRect || {};
                    var s = document;
                    return !e.settings.multiline && s.all && (!s.documentMode || s.documentMode <= 8) && (t.lineHeight = n.h - o + "px"), r = e.borderBox, i = r.left + r.right + 8, o = r.top + r.bottom + (e.settings.multiline ? 8 : 0), n.x !== a.x && (t.left = n.x + "px", a.x = n.x), n.y !== a.y && (t.top = n.y + "px", a.y = n.y), n.w !== a.w && (t.width = n.w - i + "px", a.w = n.w), n.h !== a.h && (t.height = n.h - o + "px", a.h = n.h), e._lastRepaintRect = a, e.fire("repaint", {}, !1), e
                },
                renderHtml: function() {
                    var e = this,
                        t = e._id,
                        n = e.settings,
                        r = e.encode(e.state.get("value"), !1),
                        i = "";
                    return "spellcheck" in n && (i += ' spellcheck="' + n.spellcheck + '"'), n.maxLength && (i += ' maxlength="' + n.maxLength + '"'), n.size && (i += ' size="' + n.size + '"'), n.subtype && (i += ' type="' + n.subtype + '"'), e.disabled() && (i += ' disabled="disabled"'), n.multiline ? '<textarea id="' + t + '" class="' + e.classes + '" ' + (n.rows ? ' rows="' + n.rows + '"' : "") + ' hidefocus="1"' + i + ">" + r + "</textarea>" : '<input id="' + t + '" class="' + e.classes + '" value="' + r + '" hidefocus="1"' + i + " />"
                },
                value: function(e) {
                    return arguments.length ? (this.state.set("value", e), this) : (this.state.get("rendered") && this.state.set("value", this.getEl().value), this.state.get("value"))
                },
                postRender: function() {
                    var e = this;
                    e._super(), e.$el.on("change", function(t) {
                        e.state.set("value", t.target.value), e.fire("change", t)
                    })
                },
                bindStates: function() {
                    var e = this;
                    return e.state.on("change:value", function(t) {
                        e.getEl().value != t.value && (e.getEl().value = t.value)
                    }), e.state.on("change:disabled", function(t) {
                        e.getEl().disabled = t.value
                    }), e._super()
                },
                remove: function() {
                    this.$el.off(), this._super()
                }
            })
        }), r(qt, [g, he, u], function(e, t, n) {
            return function(r, i) {
                var o = this,
                    a, s = t.classPrefix;
                o.show = function(t, l) {
                    return o.hide(), a = !0, n.setTimeout(function() {
                        a && (e(r).append('<div class="' + s + "throbber" + (i ? " " + s + "throbber-inline" : "") + '"></div>'), l && l())
                    }, t), o
                }, o.hide = function() {
                    var e = r.lastChild;
                    return e && -1 != e.className.indexOf("throbber") && e.parentNode.removeChild(e), a = !1, o
                }
            }
        }), a([l, c, u, d, f, h, m, g, v, y, C, w, E, N, T, A, B, D, M, L, P, H, I, F, j, Y, G, J, ee, te, ne, re, oe, se, le, fe, he, pe, me, ge, ve, ye, be, Ce, xe, we, Ee, Ne, _e, Se, ke, Te, Re, Ae, Me, Pe, Ke, Ge, Je, Qe, et, tt, nt, rt, it, ot, at, st, lt, ct, ut, dt, ft, ht, pt, mt, gt, vt, yt, bt, Ct, xt, wt, Et, Nt, _t, St, kt, Tt, Rt, At, Bt, Dt, Mt, Lt, Pt, Ht, Ot, It, Ft, zt, Wt, Vt, Ut, $t, qt])
    }(this);
    /*! RESOURCE: /scripts/sp-tinymce/themes/modern/theme.min.js */
    tinymce.ThemeManager.add("modern", function(e) {
        function t(t, n) {
            var r, i = [];
            if (t) return h(t.split(/[ ,]/), function(t) {
                function o() {
                    function n(e) {
                        return function(n, r) {
                            for (var i, o = r.parents.length; o-- && (i = r.parents[o].nodeName, "OL" != i && "UL" != i););
                            t.active(n && i == e)
                        }
                    }
                    var r = e.selection;
                    "bullist" == a && r.selectorChanged("ul > li", n("UL")), "numlist" == a && r.selectorChanged("ol > li", n("OL")), t.settings.stateSelector && r.selectorChanged(t.settings.stateSelector, function(e) {
                        t.active(e)
                    }, !0), t.settings.disabledStateSelector && r.selectorChanged(t.settings.disabledStateSelector, function(e) {
                        t.disabled(e)
                    })
                }
                var a;
                "|" == t ? r = null : f.has(t) ? (t = {
                    type: t,
                    size: n
                }, i.push(t), r = null) : (r || (r = {
                    type: "buttongroup",
                    items: []
                }, i.push(r)), e.buttons[t] && (a = t, t = e.buttons[a], "function" == typeof t && (t = t()), t.type = t.type || "button", t.size = n, t = f.create(t), r.items.push(t), e.initialized ? o() : e.on("init", o)))
            }), {
                type: "toolbar",
                layout: "flow",
                items: i
            }
        }
    
        function n(e) {
            function n(n) {
                return n ? (r.push(t(n, e)), !0) : void 0
            }
            var r = [];
            if (tinymce.isArray(d.toolbar)) {
                if (0 === d.toolbar.length) return;
                tinymce.each(d.toolbar, function(e, t) {
                    d["toolbar" + (t + 1)] = e
                }), delete d.toolbar
            }
            for (var i = 1; 10 > i && n(d["toolbar" + i]); i++);
            return r.length || d.toolbar === !1 || n(d.toolbar || y), r.length ? {
                type: "panel",
                layout: "stack",
                classes: "toolbar-grp",
                ariaRoot: !0,
                ariaRemember: !0,
                items: r
            } : void 0
        }
    
        function r() {
            function t(t) {
                var n;
                return "|" == t ? {
                    text: "|"
                } : n = e.menuItems[t]
            }
    
            function n(n) {
                var r, i, o, a, s;
                if (s = tinymce.makeMap((d.removed_menuitems || "").split(/[ ,]/)), d.menu ? (i = d.menu[n], a = !0) : i = v[n], i) {
                    r = {
                        text: i.title
                    }, o = [], h((i.items || "").split(/[ ,]/), function(e) {
                        var n = t(e);
                        n && !s[e] && o.push(t(e))
                    }), a || h(e.menuItems, function(e) {
                        e.context == n && ("before" == e.separator && o.push({
                            text: "|"
                        }), e.prependToContext ? o.unshift(e) : o.push(e), "after" == e.separator && o.push({
                            text: "|"
                        }))
                    });
                    for (var l = 0; l < o.length; l++) "|" == o[l].text && (0 === l || l == o.length - 1) && o.splice(l, 1);
                    if (r.menu = o, !r.menu.length) return null
                }
                return r
            }
            var r, i = [],
                o = [];
            if (d.menu)
                for (r in d.menu) o.push(r);
            else
                for (r in v) o.push(r);
            for (var a = "string" == typeof d.menubar ? d.menubar.split(/[ ,]/) : o, s = 0; s < a.length; s++) {
                var l = a[s];
                l = n(l), l && i.push(l)
            }
            return i
        }
    
        function i(t) {
            function n(e) {
                var n = t.find(e)[0];
                n && n.focus(!0)
            }
            e.shortcuts.add("Alt+F9", "", function() {
                n("menubar")
            }), e.shortcuts.add("Alt+F10", "", function() {
                n("toolbar")
            }), e.shortcuts.add("Alt+F11", "", function() {
                n("elementpath")
            }), t.on("cancel", function() {
                e.focus()
            })
        }
    
        function o(t, n) {
            function r(e) {
                return {
                    width: e.clientWidth,
                    height: e.clientHeight
                }
            }
            var i, o, a, s;
            i = e.getContainer(), o = e.getContentAreaContainer().firstChild, a = r(i), s = r(o), null !== t && (t = Math.max(d.min_width || 100, t), t = Math.min(d.max_width || 65535, t), m.setStyle(i, "width", t + (a.width - s.width)), m.setStyle(o, "width", t)), n = Math.max(d.min_height || 100, n), n = Math.min(d.max_height || 65535, n), m.setStyle(o, "height", n), e.fire("ResizeEditor")
        }
    
        function a(t, n) {
            var r = e.getContentAreaContainer();
            u.resizeTo(r.clientWidth + t, r.clientHeight + n)
        }
    
        function s() {
            function n() {
                return e.contextToolbars || []
            }
    
            function r(t) {
                var n, r, i;
                return n = tinymce.DOM.getPos(e.getContentAreaContainer()), r = e.dom.getRect(t), i = e.dom.getRoot(), "BODY" == i.nodeName && (r.x -= i.ownerDocument.documentElement.scrollLeft || i.scrollLeft, r.y -= i.ownerDocument.documentElement.scrollTop || i.scrollTop), r.x += n.x, r.y += n.y, r
            }
    
            function i() {
                h(e.contextToolbars, function(e) {
                    e.panel && e.panel.hide()
                })
            }
    
            function o(t) {
                var n, o, a, s, l, c, u;
                if (!e.removed) {
                    if (!t || !t.toolbar.panel) return void i();
                    u = ["tc-bc", "bc-tc", "tl-bl", "bl-tl", "tr-br", "br-tr"], l = t.toolbar.panel, l.show(), a = r(t.element), o = tinymce.DOM.getRect(l.getEl()), s = tinymce.DOM.getRect(e.getContentAreaContainer() || e.getBody()), a.w = t.element.clientWidth, a.h = t.element.clientHeight, e.inline || (s.w = e.getDoc().documentElement.offsetWidth), e.selection.controlSelection.isResizable(t.element) && (a = p.inflate(a, 0, 8)), n = p.findBestRelativePosition(o, a, s, u), n ? (h(u.concat("inside"), function(e) {
                        l.classes.toggle("tinymce-inline-" + e, e == n)
                    }), c = p.relativePosition(o, a, n), l.moveTo(c.x, c.y)) : (h(u, function(e) {
                        l.classes.toggle("tinymce-inline-" + e, !1)
                    }), l.classes.toggle("tinymce-inline-inside", !0), a = p.intersect(s, a), a ? (n = p.findBestRelativePosition(o, a, s, ["tc-tc", "tl-tl", "tr-tr"]), n ? (c = p.relativePosition(o, a, n), l.moveTo(c.x, c.y)) : l.moveTo(a.x, a.y)) : l.hide())
                }
            }
    
            function a() {
                function t() {
                    e.selection && o(u(e.selection.getNode()))
                }
                tinymce.util.Delay.requestAnimationFrame(t)
            }
    
            function s() {
                d || (d = e.selection.getScrollContainer() || e.getWin(), tinymce.$(d).on("scroll", a), e.on("remove", function() {
                    tinymce.$(d).off("scroll")
                }))
            }
    
            function l(e) {
                var n;
                return e.toolbar.panel ? (e.toolbar.panel.show(), void o(e)) : (s(), n = f.create({
                    type: "floatpanel",
                    role: "application",
                    classes: "tinymce tinymce-inline",
                    layout: "flex",
                    direction: "column",
                    align: "stretch",
                    autohide: !1,
                    autofix: !0,
                    fixed: !0,
                    border: 1,
                    items: t(e.toolbar.items)
                }), e.toolbar.panel = n, n.renderTo(document.body).reflow(), void o(e))
            }
    
            function c() {
                tinymce.each(n(), function(e) {
                    e.panel && e.panel.hide()
                })
            }
    
            function u(t) {
                var r, i, o, a = n();
                for (o = e.$(t).parents().add(t), r = o.length - 1; r >= 0; r--)
                    for (i = a.length - 1; i >= 0; i--)
                        if (a[i].predicate(o[r])) return {
                            toolbar: a[i],
                            element: o[r]
                        };
                return null
            }
            var d;
            e.on("click keyup setContent", function(t) {
                ("setcontent" != t.type || t.selection) && tinymce.util.Delay.setEditorTimeout(e, function() {
                    var t;
                    t = u(e.selection.getNode()), t ? (c(), l(t)) : c()
                })
            }), e.on("blur hide", c), e.on("ObjectResizeStart", function() {
                var t = u(e.selection.getNode());
                t && t.toolbar.panel && t.toolbar.panel.hide()
            }), e.on("nodeChange ResizeEditor ResizeWindow", a), e.on("remove", function() {
                tinymce.each(n(), function(e) {
                    e.panel && e.panel.remove()
                }), e.contextToolbars = {}
            })
        }
    
        function l(t) {
            function o() {
                if (h && h.moveRel && h.visible() && !h._fixed) {
                    var t = e.selection.getScrollContainer(),
                        n = e.getBody(),
                        r = 0,
                        i = 0;
                    if (t) {
                        var o = m.getPos(n),
                            a = m.getPos(t);
                        r = Math.max(0, a.x - o.x), i = Math.max(0, a.y - o.y)
                    }
                    h.fixed(!1).moveRel(n, e.rtl ? ["tr-br", "br-tr"] : ["tl-bl", "bl-tl", "tr-br"]).moveBy(r, i)
                }
            }
    
            function a() {
                h && (h.show(), o(), m.addClass(e.getBody(), "mce-edit-focus"))
            }
    
            function l() {
                h && (h.hide(), g.hideAll(), m.removeClass(e.getBody(), "mce-edit-focus"))
            }
    
            function c() {
                return h ? void(h.visible() || a()) : (h = u.panel = f.create({
                    type: p ? "panel" : "floatpanel",
                    role: "application",
                    classes: "tinymce tinymce-inline",
                    layout: "flex",
                    direction: "column",
                    align: "stretch",
                    autohide: !1,
                    autofix: !0,
                    fixed: !!p,
                    border: 1,
                    items: [d.menubar === !1 ? null : {
                        type: "menubar",
                        border: "0 0 1 0",
                        items: r()
                    }, n(d.toolbar_items_size)]
                }), e.fire("BeforeRenderUI"), h.renderTo(p || document.body).reflow(), i(h), a(), s(), e.on("nodeChange", o), e.on("activate", a), e.on("deactivate", l), void e.nodeChanged())
            }
            var h, p;
            return d.fixed_toolbar_container && (p = m.select(d.fixed_toolbar_container)[0]), d.content_editable = !0, e.on("focus", function() {
                t.skinUiCss ? tinymce.DOM.styleSheetLoader.load(t.skinUiCss, c, c) : c()
            }), e.on("blur hide", l), e.on("remove", function() {
                h && (h.remove(), h = null)
            }), t.skinUiCss && tinymce.DOM.styleSheetLoader.load(t.skinUiCss), {}
        }
    
        function c(t) {
            function a() {
                return function(e) {
                    "readonly" == e.mode ? l.find("*").disabled(!0) : l.find("*").disabled(!1)
                }
            }
            var l, c, h;
            return t.skinUiCss && tinymce.DOM.loadCSS(t.skinUiCss), l = u.panel = f.create({
                type: "panel",
                role: "application",
                classes: "tinymce",
                style: "visibility: hidden",
                layout: "stack",
                border: 1,
                items: [d.menubar === !1 ? null : {
                    type: "menubar",
                    border: "0 0 1 0",
                    items: r()
                }, n(d.toolbar_items_size), {
                    type: "panel",
                    name: "iframe",
                    layout: "stack",
                    classes: "edit-area",
                    html: "",
                    border: "1 0 0 0"
                }]
            }), d.resize !== !1 && (c = {
                type: "resizehandle",
                direction: d.resize,
                onResizeStart: function() {
                    var t = e.getContentAreaContainer().firstChild;
                    h = {
                        width: t.clientWidth,
                        height: t.clientHeight
                    }
                },
                onResize: function(e) {
                    "both" == d.resize ? o(h.width + e.deltaX, h.height + e.deltaY) : o(null, h.height + e.deltaY)
                }
            }), d.statusbar !== !1 && l.add({
                type: "panel",
                name: "statusbar",
                classes: "statusbar",
                layout: "flow",
                border: "1 0 0 0",
                ariaRoot: !0,
                items: [{
                    type: "elementpath"
                }, c]
            }), d.readonly && l.find("*").disabled(!0), e.fire("BeforeRenderUI"), e.on("SwitchMode", a()), l.renderBefore(t.targetNode).reflow(), d.width && tinymce.DOM.setStyle(l.getEl(), "width", d.width), e.on("remove", function() {
                l.remove(), l = null
            }), i(l), s(), {
                iframeContainer: l.find("#iframe")[0].getEl(),
                editorContainer: l.getEl()
            }
        }
        var u = this,
            d = e.settings,
            f = tinymce.ui.Factory,
            h = tinymce.each,
            m = tinymce.DOM,
            p = tinymce.geom.Rect,
            g = tinymce.ui.FloatPanel,
            v = {
                file: {
                    title: "File",
                    items: "newdocument"
                },
                edit: {
                    title: "Edit",
                    items: "undo redo | cut copy paste pastetext | selectall"
                },
                insert: {
                    title: "Insert",
                    items: "|"
                },
                view: {
                    title: "View",
                    items: "visualaid |"
                },
                format: {
                    title: "Format",
                    items: "bold italic underline strikethrough superscript subscript | formats | removeformat"
                },
                table: {
                    title: "Table"
                },
                tools: {
                    title: "Tools"
                }
            },
            y = "undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image";
        u.renderUI = function(t) {
            var n = d.skin !== !1 ? d.skin || "lightgray" : !1;
            if (n) {
                var r = d.skin_url;
                r = r ? e.documentBaseURI.toAbsolute(r) : tinymce.baseURL + "/skins/" + n, tinymce.Env.documentMode <= 7 ? t.skinUiCss = r + "/skin.ie7.min.css" : t.skinUiCss = r + "/skin.min.css", e.contentCSS.push(r + "/content" + (e.inline ? ".inline" : "") + ".min.css")
            }
            return e.on("ProgressState", function(e) {
                u.throbber = u.throbber || new tinymce.ui.Throbber(u.panel.getEl("body")), e.state ? u.throbber.show(e.time) : u.throbber.hide()
            }), d.inline ? l(t) : c(t)
        }, u.resizeTo = o, u.resizeBy = a
    });;
    /*! RESOURCE: /scripts/angular-ui-tinymce.js */
    angular.module('ui.tinymce', [])
        .value('uiTinymceConfig', {})
        .directive('uiTinymce', ['$rootScope', '$compile', '$timeout', '$window', '$sce', 'uiTinymceConfig', function($rootScope, $compile, $timeout, $window, $sce, uiTinymceConfig) {
            uiTinymceConfig = uiTinymceConfig || {};
            var generatedIds = 0;
            var ID_ATTR = 'ui-tinymce';
            if (uiTinymceConfig.baseUrl) {
                tinymce.baseURL = uiTinymceConfig.baseUrl;
            }
            return {
                require: ['ngModel', '^?form'],
                priority: 599,
                link: function(scope, element, attrs, ctrls) {
                    if (!$window.tinymce) {
                        return;
                    }
                    var ngModel = ctrls[0],
                        form = ctrls[1] || null;
                    var expression, options = {
                            debounce: true
                        },
                        tinyInstance,
                        updateView = function(editor) {
                            var content = editor.getContent({
                                format: options.format
                            }).trim();
                            content = $sce.trustAsHtml(content);
                            ngModel.$setViewValue(content);
                            if (!$rootScope.$$phase) {
                                scope.$digest();
                            }
                        };
    
                    function toggleDisable(disabled) {
                        if (disabled) {
                            ensureInstance();
                            if (tinyInstance) {
                                tinyInstance.getBody().setAttribute('contenteditable', false);
                            }
                        } else {
                            ensureInstance();
                            if (tinyInstance && !tinyInstance.settings.readonly) {
                                tinyInstance.getBody().setAttribute('contenteditable', true);
                            }
                        }
                    }
                    attrs.$set('id', ID_ATTR + '-' + generatedIds++);
                    expression = {};
                    angular.extend(expression, scope.$eval(attrs.uiTinymce));
                    var debouncedUpdate = (function(debouncedUpdateDelay) {
                        var debouncedUpdateTimer;
                        return function(ed) {
                            $timeout.cancel(debouncedUpdateTimer);
                            debouncedUpdateTimer = $timeout(function() {
                                return (function(ed) {
                                    if (ed.isDirty()) {
                                        ed.save();
                                        updateView(ed);
                                    }
                                })(ed);
                            }, debouncedUpdateDelay);
                        };
                    })(400);
                    var setupOptions = {
                        setup: function(ed) {
                            ed.on('init', function() {
                                ngModel.$render();
                                ngModel.$setPristine();
                                ngModel.$setUntouched();
                                if (form) {
                                    form.$setPristine();
                                }
                            });
                            ed.on('ExecCommand change NodeChange ObjectResized', function() {
                                if (!options.debounce) {
                                    ed.save();
                                    updateView(ed);
                                    return;
                                }
                                debouncedUpdate(ed);
                            });
                            ed.on('blur', function() {
                                element[0].blur();
                                ngModel.$setTouched();
                                if (!$rootScope.$$phase) {
                                    scope.$digest();
                                }
                            });
                            ed.on('remove', function() {
                                element.remove();
                            });
                            if (uiTinymceConfig.setup) {
                                uiTinymceConfig.setup(ed, {
                                    updateView: updateView
                                });
                            }
                            if (expression.setup) {
                                expression.setup(ed, {
                                    updateView: updateView
                                });
                            }
                        },
                        format: expression.format || 'html',
                        selector: '#' + attrs.id
                    };
                    angular.extend(options, uiTinymceConfig, expression, setupOptions);
                    $timeout(function() {
                        if (options.baseURL) {
                            tinymce.baseURL = options.baseURL;
                        }
                        tinymce.init(options);
                        toggleDisable(scope.$eval(attrs.ngDisabled));
                    });
                    ngModel.$formatters.unshift(function(modelValue) {
                        return modelValue ? $sce.trustAsHtml(modelValue) : '';
                    });
                    ngModel.$parsers.unshift(function(viewValue) {
                        return viewValue ? $sce.getTrustedHtml(viewValue) : '';
                    });
                    ngModel.$render = function() {
                        ensureInstance();
                        var viewValue = ngModel.$viewValue ?
                            $sce.getTrustedHtml(ngModel.$viewValue) : '';
                        if (tinyInstance &&
                            tinyInstance.getDoc()
                        ) {
                            tinyInstance.setContent(viewValue);
                            tinyInstance.fire('change');
                        }
                    };
                    attrs.$observe('disabled', toggleDisable);
                    scope.$on('$tinymce:refresh', function(e, id) {
                        var eid = attrs.id;
                        if (angular.isUndefined(id) || id === eid) {
                            var parentElement = element.parent();
                            var clonedElement = element.clone();
                            clonedElement.removeAttr('id');
                            clonedElement.removeAttr('style');
                            clonedElement.removeAttr('aria-hidden');
                            tinymce.execCommand('mceRemoveEditor', false, eid);
                            parentElement.append($compile(clonedElement)(scope));
                        }
                    });
                    scope.$on('$destroy', function() {
                        ensureInstance();
                        if (tinyInstance) {
                            tinyInstance.remove();
                            tinyInstance = null;
                        }
                    });
    
                    function ensureInstance() {
                        if (!tinyInstance) {
                            tinyInstance = tinymce.get(attrs.id);
                        }
                    }
                }
            };
        }]);;
    /*! RESOURCE: /scripts/sp-tinymce/decorator.uiTinymce.js */
    angular.module('ui.tinymce').config(function($provide) {
        $provide.decorator('uiTinymceDirective', function($delegate) {
            tinyMCE.baseURL = "/scripts/sp-tinymce";
            tinyMCE.suffix = '.min';
            $delegate[0].priority = 10;
            return $delegate;
        })
    });;
    /*! RESOURCE: /scripts/prism/prism.js */
    var _self = "undefined" != typeof window ? window : "undefined" != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope ? self : {},
        Prism = function() {
            var e = /\blang(?:uage)?-(\w+)\b/i,
                t = _self.Prism = {
                    util: {
                        encode: function(e) {
                            return e instanceof n ? new n(e.type, t.util.encode(e.content), e.alias) : "Array" === t.util.type(e) ? e.map(t.util.encode) : e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/\u00a0/g, " ")
                        },
                        type: function(e) {
                            return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]
                        },
                        clone: function(e) {
                            var n = t.util.type(e);
                            switch (n) {
                                case "Object":
                                    var a = {};
                                    for (var r in e) e.hasOwnProperty(r) && (a[r] = t.util.clone(e[r]));
                                    return a;
                                case "Array":
                                    return e.map && e.map(function(e) {
                                        return t.util.clone(e)
                                    })
                            }
                            return e
                        }
                    },
                    languages: {
                        extend: function(e, n) {
                            var a = t.util.clone(t.languages[e]);
                            for (var r in n) a[r] = n[r];
                            return a
                        },
                        insertBefore: function(e, n, a, r) {
                            r = r || t.languages;
                            var l = r[e];
                            if (2 == arguments.length) {
                                a = arguments[1];
                                for (var i in a) a.hasOwnProperty(i) && (l[i] = a[i]);
                                return l
                            }
                            var o = {};
                            for (var s in l)
                                if (l.hasOwnProperty(s)) {
                                    if (s == n)
                                        for (var i in a) a.hasOwnProperty(i) && (o[i] = a[i]);
                                    o[s] = l[s]
                                }
                            return t.languages.DFS(t.languages, function(t, n) {
                                n === r[e] && t != e && (this[t] = o)
                            }), r[e] = o
                        },
                        DFS: function(e, n, a, r) {
                            r = r || {};
                            for (var l in e) e.hasOwnProperty(l) && (n.call(e, l, e[l], a || l), "Object" !== t.util.type(e[l]) || r[e[l]] ? "Array" !== t.util.type(e[l]) || r[e[l]] || (r[e[l]] = !0, t.languages.DFS(e[l], n, l, r)) : (r[e[l]] = !0, t.languages.DFS(e[l], n, null, r)))
                        }
                    },
                    plugins: {},
                    highlightAll: function(e, n) {
                        for (var a, r = document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'), l = 0; a = r[l++];) t.highlightElement(a, e === !0, n)
                    },
                    highlightElement: function(n, a, r) {
                        for (var l, i, o = n; o && !e.test(o.className);) o = o.parentNode;
                        o && (l = (o.className.match(e) || [, ""])[1], i = t.languages[l]), n.className = n.className.replace(e, "").replace(/\s+/g, " ") + " language-" + l, o = n.parentNode, /pre/i.test(o.nodeName) && (o.className = o.className.replace(e, "").replace(/\s+/g, " ") + " language-" + l);
                        var s = n.textContent,
                            u = {
                                element: n,
                                language: l,
                                grammar: i,
                                code: s
                            };
                        if (!s || !i) return t.hooks.run("complete", u), void 0;
                        if (t.hooks.run("before-highlight", u), a && _self.Worker) {
                            var c = new Worker(t.filename);
                            c.onmessage = function(e) {
                                u.highlightedCode = e.data, t.hooks.run("before-insert", u), u.element.innerHTML = u.highlightedCode, r && r.call(u.element), t.hooks.run("after-highlight", u), t.hooks.run("complete", u)
                            }, c.postMessage(JSON.stringify({
                                language: u.language,
                                code: u.code,
                                immediateClose: !0
                            }))
                        } else u.highlightedCode = t.highlight(u.code, u.grammar, u.language), t.hooks.run("before-insert", u), u.element.innerHTML = u.highlightedCode, r && r.call(n), t.hooks.run("after-highlight", u), t.hooks.run("complete", u)
                    },
                    highlight: function(e, a, r) {
                        var l = t.tokenize(e, a);
                        return n.stringify(t.util.encode(l), r)
                    },
                    tokenize: function(e, n) {
                        var a = t.Token,
                            r = [e],
                            l = n.rest;
                        if (l) {
                            for (var i in l) n[i] = l[i];
                            delete n.rest
                        }
                        e: for (var i in n)
                            if (n.hasOwnProperty(i) && n[i]) {
                                var o = n[i];
                                o = "Array" === t.util.type(o) ? o : [o];
                                for (var s = 0; s < o.length; ++s) {
                                    var u = o[s],
                                        c = u.inside,
                                        g = !!u.lookbehind,
                                        f = 0,
                                        h = u.alias;
                                    u = u.pattern || u;
                                    for (var p = 0; p < r.length; p++) {
                                        var d = r[p];
                                        if (r.length > e.length) break e;
                                        if (!(d instanceof a)) {
                                            u.lastIndex = 0;
                                            var m = u.exec(d);
                                            if (m) {
                                                g && (f = m[1].length);
                                                var y = m.index - 1 + f,
                                                    m = m[0].slice(f),
                                                    v = m.length,
                                                    k = y + v,
                                                    b = d.slice(0, y + 1),
                                                    w = d.slice(k + 1),
                                                    P = [p, 1];
                                                b && P.push(b);
                                                var A = new a(i, c ? t.tokenize(m, c) : m, h);
                                                P.push(A), w && P.push(w), Array.prototype.splice.apply(r, P)
                                            }
                                        }
                                    }
                                }
                            }
                        return r
                    },
                    hooks: {
                        all: {},
                        add: function(e, n) {
                            var a = t.hooks.all;
                            a[e] = a[e] || [], a[e].push(n)
                        },
                        run: function(e, n) {
                            var a = t.hooks.all[e];
                            if (a && a.length)
                                for (var r, l = 0; r = a[l++];) r(n)
                        }
                    }
                },
                n = t.Token = function(e, t, n) {
                    this.type = e, this.content = t, this.alias = n
                };
            if (n.stringify = function(e, a, r) {
                    if ("string" == typeof e) return e;
                    if ("Array" === t.util.type(e)) return e.map(function(t) {
                        return n.stringify(t, a, e)
                    }).join("");
                    var l = {
                        type: e.type,
                        content: n.stringify(e.content, a, r),
                        tag: "span",
                        classes: ["token", e.type],
                        attributes: {},
                        language: a,
                        parent: r
                    };
                    if ("comment" == l.type && (l.attributes.spellcheck = "true"), e.alias) {
                        var i = "Array" === t.util.type(e.alias) ? e.alias : [e.alias];
                        Array.prototype.push.apply(l.classes, i)
                    }
                    t.hooks.run("wrap", l);
                    var o = "";
                    for (var s in l.attributes) o += (o ? " " : "") + s + '="' + (l.attributes[s] || "") + '"';
                    return "<" + l.tag + ' class="' + l.classes.join(" ") + '" ' + o + ">" + l.content + "</" + l.tag + ">"
                }, !_self.document) return _self.addEventListener ? (_self.addEventListener("message", function(e) {
                var n = JSON.parse(e.data),
                    a = n.language,
                    r = n.code,
                    l = n.immediateClose;
                _self.postMessage(t.highlight(r, t.languages[a], a)), l && _self.close()
            }, !1), _self.Prism) : _self.Prism;
            var a = document.currentScript || [].slice.call(document.getElementsByTagName("script")).pop();
            return a && (t.filename = a.src, document.addEventListener && !a.hasAttribute("data-manual") && document.addEventListener("DOMContentLoaded", t.highlightAll)), _self.Prism
        }();
    "undefined" != typeof module && module.exports && (module.exports = Prism), "undefined" != typeof global && (global.Prism = Prism);
    Prism.languages.markup = {
        comment: /<!--[\w\W]*?-->/,
        prolog: /<\?[\w\W]+?\?>/,
        doctype: /<!DOCTYPE[\w\W]+?>/,
        cdata: /<!\[CDATA\[[\w\W]*?]]>/i,
        tag: {
            pattern: /<\/?(?!\d)[^\s>\/=.$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,
            inside: {
                tag: {
                    pattern: /^<\/?[^\s>\/]+/i,
                    inside: {
                        punctuation: /^<\/?/,
                        namespace: /^[^\s>\/:]+:/
                    }
                },
                "attr-value": {
                    pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,
                    inside: {
                        punctuation: /[=>"']/
                    }
                },
                punctuation: /\/?>/,
                "attr-name": {
                    pattern: /[^\s>\/]+/,
                    inside: {
                        namespace: /^[^\s>\/:]+:/
                    }
                }
            }
        },
        entity: /&#?[\da-z]{1,8};/i
    }, Prism.hooks.add("wrap", function(a) {
        "entity" === a.type && (a.attributes.title = a.content.replace(/&amp;/, "&"))
    }), Prism.languages.xml = Prism.languages.markup, Prism.languages.html = Prism.languages.markup, Prism.languages.mathml = Prism.languages.markup, Prism.languages.svg = Prism.languages.markup;
    Prism.languages.css = {
        comment: /\/\*[\w\W]*?\*\//,
        atrule: {
            pattern: /@[\w-]+?.*?(;|(?=\s*\{))/i,
            inside: {
                rule: /@[\w-]+/
            }
        },
        url: /url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,
        selector: /[^\{\}\s][^\{\};]*?(?=\s*\{)/,
        string: /("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/,
        property: /(\b|\B)[\w-]+(?=\s*:)/i,
        important: /\B!important\b/i,
        "function": /[-a-z0-9]+(?=\()/i,
        punctuation: /[(){};:]/
    }, Prism.languages.css.atrule.inside.rest = Prism.util.clone(Prism.languages.css), Prism.languages.markup && (Prism.languages.insertBefore("markup", "tag", {
        style: {
            pattern: /(<style[\w\W]*?>)[\w\W]*?(?=<\/style>)/i,
            lookbehind: !0,
            inside: Prism.languages.css,
            alias: "language-css"
        }
    }), Prism.languages.insertBefore("inside", "attr-value", {
        "style-attr": {
            pattern: /\s*style=("|').*?\1/i,
            inside: {
                "attr-name": {
                    pattern: /^\s*style/i,
                    inside: Prism.languages.markup.tag.inside
                },
                punctuation: /^\s*=\s*['"]|['"]\s*$/,
                "attr-value": {
                    pattern: /.+/i,
                    inside: Prism.languages.css
                }
            },
            alias: "language-css"
        }
    }, Prism.languages.markup.tag));
    Prism.languages.clike = {
        comment: [{
            pattern: /(^|[^\\])\/\*[\w\W]*?\*\//,
            lookbehind: !0
        }, {
            pattern: /(^|[^\\:])\/\/.*/,
            lookbehind: !0
        }],
        string: /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
        "class-name": {
            pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,
            lookbehind: !0,
            inside: {
                punctuation: /(\.|\\)/
            }
        },
        keyword: /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
        "boolean": /\b(true|false)\b/,
        "function": /[a-z0-9_]+(?=\()/i,
        number: /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,
        operator: /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,
        punctuation: /[{}[\];(),.:]/
    };
    Prism.languages.javascript = Prism.languages.extend("clike", {
        keyword: /\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,
        number: /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,
        "function": /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i
    }), Prism.languages.insertBefore("javascript", "keyword", {
        regex: {
            pattern: /(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,
            lookbehind: !0
        }
    }), Prism.languages.insertBefore("javascript", "class-name", {
        "template-string": {
            pattern: /`(?:\\`|\\?[^`])*`/,
            inside: {
                interpolation: {
                    pattern: /\$\{[^}]+\}/,
                    inside: {
                        "interpolation-punctuation": {
                            pattern: /^\$\{|\}$/,
                            alias: "punctuation"
                        },
                        rest: Prism.languages.javascript
                    }
                },
                string: /[\s\S]+/
            }
        }
    }), Prism.languages.markup && Prism.languages.insertBefore("markup", "tag", {
        script: {
            pattern: /(<script[\w\W]*?>)[\w\W]*?(?=<\/script>)/i,
            lookbehind: !0,
            inside: Prism.languages.javascript,
            alias: "language-javascript"
        }
    }), Prism.languages.js = Prism.languages.javascript;
    ! function(e) {
        e.languages.ruby = e.languages.extend("clike", {
            comment: /#(?!\{[^\r\n]*?\}).*/,
            keyword: /\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/
        });
        var n = {
            pattern: /#\{[^}]+\}/,
            inside: {
                delimiter: {
                    pattern: /^#\{|\}$/,
                    alias: "tag"
                },
                rest: e.util.clone(e.languages.ruby)
            }
        };
        e.languages.insertBefore("ruby", "keyword", {
            regex: [{
                pattern: /%r([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1[gim]{0,3}/,
                inside: {
                    interpolation: n
                }
            }, {
                pattern: /%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,
                inside: {
                    interpolation: n
                }
            }, {
                pattern: /%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,
                inside: {
                    interpolation: n
                }
            }, {
                pattern: /%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,
                inside: {
                    interpolation: n
                }
            }, {
                pattern: /%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,
                inside: {
                    interpolation: n
                }
            }, {
                pattern: /(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,
                lookbehind: !0
            }],
            variable: /[@$]+[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/,
            symbol: /:[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/
        }), e.languages.insertBefore("ruby", "number", {
            builtin: /\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Fload|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,
            constant: /\b[A-Z][a-zA-Z_0-9]*(?:[?!]|\b)/
        }), e.languages.ruby.string = [{
            pattern: /%[qQiIwWxs]?([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1/,
            inside: {
                interpolation: n
            }
        }, {
            pattern: /%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,
            inside: {
                interpolation: n
            }
        }, {
            pattern: /%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,
            inside: {
                interpolation: n
            }
        }, {
            pattern: /%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,
            inside: {
                interpolation: n
            }
        }, {
            pattern: /%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,
            inside: {
                interpolation: n
            }
        }, {
            pattern: /("|')(#\{[^}]+\}|\\(?:\r?\n|\r)|\\?.)*?\1/,
            inside: {
                interpolation: n
            }
        }]
    }(Prism);
    Prism.languages.java = Prism.languages.extend("clike", {
        keyword: /\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/,
        number: /\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+(?:e[+-]?\d+)?[df]?\b/i,
        operator: {
            pattern: /(^|[^.])(?:\+[+=]?|-[-=]?|!=?|<<?=?|>>?>?=?|==?|&[&=]?|\|[|=]?|\*=?|\/=?|%=?|\^=?|[?:~])/m,
            lookbehind: !0
        }
    });
    Prism.languages.php = Prism.languages.extend("clike", {
        keyword: /\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i,
        constant: /\b[A-Z0-9_]{2,}\b/,
        comment: {
            pattern: /(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/,
            lookbehind: !0
        }
    }), Prism.languages.insertBefore("php", "class-name", {
        "shell-comment": {
            pattern: /(^|[^\\])#.*/,
            lookbehind: !0,
            alias: "comment"
        }
    }), Prism.languages.insertBefore("php", "keyword", {
        delimiter: /\?>|<\?(?:php)?/i,
        variable: /\$\w+\b/i,
        "package": {
            pattern: /(\\|namespace\s+|use\s+)[\w\\]+/,
            lookbehind: !0,
            inside: {
                punctuation: /\\/
            }
        }
    }), Prism.languages.insertBefore("php", "operator", {
        property: {
            pattern: /(->)[\w]+/,
            lookbehind: !0
        }
    }), Prism.languages.markup && (Prism.hooks.add("before-highlight", function(e) {
        "php" === e.language && (e.tokenStack = [], e.backupCode = e.code, e.code = e.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/gi, function(a) {
            return e.tokenStack.push(a), "{{{PHP" + e.tokenStack.length + "}}}"
        }))
    }), Prism.hooks.add("before-insert", function(e) {
        "php" === e.language && (e.code = e.backupCode, delete e.backupCode)
    }), Prism.hooks.add("after-highlight", function(e) {
        if ("php" === e.language) {
            for (var a, n = 0; a = e.tokenStack[n]; n++) e.highlightedCode = e.highlightedCode.replace("{{{PHP" + (n + 1) + "}}}", Prism.highlight(a, e.grammar, "php").replace(/\$/g, "$$$$"));
            e.element.innerHTML = e.highlightedCode
        }
    }), Prism.hooks.add("wrap", function(e) {
        "php" === e.language && "markup" === e.type && (e.content = e.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g, '<span class="token php">$1</span>'))
    }), Prism.languages.insertBefore("php", "comment", {
        markup: {
            pattern: /<[^?]\/?(.*?)>/,
            inside: Prism.languages.markup
        },
        php: /\{\{\{PHP[0-9]+\}\}\}/
    }));
    Prism.languages.python = {
        "triple-quoted-string": {
            pattern: /"""[\s\S]+?"""|'''[\s\S]+?'''/,
            alias: "string"
        },
        comment: {
            pattern: /(^|[^\\])#.*/,
            lookbehind: !0
        },
        string: /("|')(?:\\?.)*?\1/,
        "function": {
            pattern: /((?:^|\s)def[ \t]+)[a-zA-Z_][a-zA-Z0-9_]*(?=\()/g,
            lookbehind: !0
        },
        "class-name": {
            pattern: /(\bclass\s+)[a-z0-9_]+/i,
            lookbehind: !0
        },
        keyword: /\b(?:as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/,
        "boolean": /\b(?:True|False)\b/,
        number: /\b-?(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,
        operator: /[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/,
        punctuation: /[{}[\];(),.:]/
    };;
    /*! RESOURCE: /scripts/libs/ng-sortable-1.3.2/ng-sortable.js */
    (function() {
        'use strict';
        angular.module('as.sortable', [])
            .constant('sortableConfig', {
                itemClass: 'as-sortable-item',
                handleClass: 'as-sortable-item-handle',
                placeHolderClass: 'as-sortable-placeholder',
                dragClass: 'as-sortable-drag',
                hiddenClass: 'as-sortable-hidden',
                dragging: 'as-sortable-dragging'
            });
    }());
    (function() {
        'use strict';
        var mainModule = angular.module('as.sortable');
        mainModule.factory('$helper', ['$document', '$window',
            function($document, $window) {
                return {
                    height: function(element) {
                        return element[0].getBoundingClientRect().height;
                    },
                    width: function(element) {
                        return element[0].getBoundingClientRect().width;
                    },
                    offset: function(element, scrollableContainer) {
                        var boundingClientRect = element[0].getBoundingClientRect();
                        if (!scrollableContainer) {
                            scrollableContainer = $document[0].documentElement;
                        }
                        return {
                            width: boundingClientRect.width || element.prop('offsetWidth'),
                            height: boundingClientRect.height || element.prop('offsetHeight'),
                            top: boundingClientRect.top + ($window.pageYOffset || scrollableContainer.scrollTop - scrollableContainer.offsetTop),
                            left: boundingClientRect.left + ($window.pageXOffset || scrollableContainer.scrollLeft - scrollableContainer.offsetLeft)
                        };
                    },
                    eventObj: function(event) {
                        var obj = event;
                        if (event.targetTouches !== undefined) {
                            obj = event.targetTouches.item(0);
                        } else if (event.originalEvent !== undefined && event.originalEvent.targetTouches !== undefined) {
                            obj = event.originalEvent.targetTouches.item(0);
                        }
                        return obj;
                    },
                    isTouchInvalid: function(event) {
                        var touchInvalid = false;
                        if (event.touches !== undefined && event.touches.length > 1) {
                            touchInvalid = true;
                        } else if (event.originalEvent !== undefined &&
                            event.originalEvent.touches !== undefined && event.originalEvent.touches.length > 1) {
                            touchInvalid = true;
                        }
                        return touchInvalid;
                    },
                    positionStarted: function(event, target, scrollableContainer) {
                        var pos = {};
                        pos.offsetX = event.pageX - this.offset(target, scrollableContainer).left;
                        pos.offsetY = event.pageY - this.offset(target, scrollableContainer).top;
                        pos.startX = pos.lastX = event.pageX;
                        pos.startY = pos.lastY = event.pageY;
                        pos.nowX = pos.nowY = pos.distX = pos.distY = pos.dirAx = 0;
                        pos.dirX = pos.dirY = pos.lastDirX = pos.lastDirY = pos.distAxX = pos.distAxY = 0;
                        return pos;
                    },
                    calculatePosition: function(pos, event) {
                        pos.lastX = pos.nowX;
                        pos.lastY = pos.nowY;
                        pos.nowX = event.pageX;
                        pos.nowY = event.pageY;
                        pos.distX = pos.nowX - pos.lastX;
                        pos.distY = pos.nowY - pos.lastY;
                        pos.lastDirX = pos.dirX;
                        pos.lastDirY = pos.dirY;
                        pos.dirX = pos.distX === 0 ? 0 : pos.distX > 0 ? 1 : -1;
                        pos.dirY = pos.distY === 0 ? 0 : pos.distY > 0 ? 1 : -1;
                        var newAx = Math.abs(pos.distX) > Math.abs(pos.distY) ? 1 : 0;
                        if (pos.dirAx !== newAx) {
                            pos.distAxX = 0;
                            pos.distAxY = 0;
                        } else {
                            pos.distAxX += Math.abs(pos.distX);
                            if (pos.dirX !== 0 && pos.dirX !== pos.lastDirX) {
                                pos.distAxX = 0;
                            }
                            pos.distAxY += Math.abs(pos.distY);
                            if (pos.dirY !== 0 && pos.dirY !== pos.lastDirY) {
                                pos.distAxY = 0;
                            }
                        }
                        pos.dirAx = newAx;
                    },
                    movePosition: function(event, element, pos, container, containerPositioning, scrollableContainer) {
                        var bounds;
                        var useRelative = (containerPositioning === 'relative');
                        element.x = event.pageX - pos.offsetX;
                        element.y = event.pageY - pos.offsetY;
                        if (container) {
                            bounds = this.offset(container, scrollableContainer);
                            if (useRelative) {
                                element.x -= bounds.left;
                                element.y -= bounds.top;
                                bounds.left = 0;
                                bounds.top = 0;
                            }
                            if (element.x < bounds.left) {
                                element.x = bounds.left;
                            } else if (element.x >= bounds.width + bounds.left - this.offset(element).width) {
                                element.x = bounds.width + bounds.left - this.offset(element).width;
                            }
                            if (element.y < bounds.top) {
                                element.y = bounds.top;
                            } else if (element.y >= bounds.height + bounds.top - this.offset(element).height) {
                                element.y = bounds.height + bounds.top - this.offset(element).height;
                            }
                        }
                        element.css({
                            'left': element.x + 'px',
                            'top': element.y + 'px'
                        });
                        this.calculatePosition(pos, event);
                    },
                    dragItem: function(item) {
                        return {
                            index: item.index(),
                            parent: item.sortableScope,
                            source: item,
                            targetElement: null,
                            targetElementOffset: null,
                            sourceInfo: {
                                index: item.index(),
                                itemScope: item.itemScope,
                                sortableScope: item.sortableScope
                            },
                            canMove: function(itemPosition, targetElement, targetElementOffset) {
                                if (this.targetElement !== targetElement) {
                                    this.targetElement = targetElement;
                                    this.targetElementOffset = targetElementOffset;
                                    return true;
                                }
                                if (itemPosition.dirX * (targetElementOffset.left - this.targetElementOffset.left) > 0 ||
                                    itemPosition.dirY * (targetElementOffset.top - this.targetElementOffset.top) > 0) {
                                    this.targetElementOffset = targetElementOffset;
                                    return true;
                                }
                                return false;
                            },
                            moveTo: function(parent, index) {
                                this.parent = parent;
                                if (this.isSameParent() && this.source.index() < index && !this.sourceInfo.sortableScope.cloning) {
                                    index = index - 1;
                                }
                                this.index = index;
                            },
                            isSameParent: function() {
                                return this.parent.element === this.sourceInfo.sortableScope.element;
                            },
                            isOrderChanged: function() {
                                return this.index !== this.sourceInfo.index;
                            },
                            eventArgs: function() {
                                return {
                                    source: this.sourceInfo,
                                    dest: {
                                        index: this.index,
                                        sortableScope: this.parent
                                    }
                                };
                            },
                            apply: function() {
                                if (!this.sourceInfo.sortableScope.cloning) {
                                    this.sourceInfo.sortableScope.removeItem(this.sourceInfo.index);
                                    if (this.parent.options.allowDuplicates || this.parent.modelValue.indexOf(this.source.modelValue) < 0) {
                                        this.parent.insertItem(this.index, this.source.modelValue);
                                    }
                                } else if (!this.parent.options.clone) {
                                    this.parent.insertItem(this.index, angular.copy(this.source.modelValue));
                                }
                            }
                        };
                    },
                    noDrag: function(element) {
                        return element.attr('no-drag') !== undefined || element.attr('data-no-drag') !== undefined;
                    },
                    findAncestor: function(el, selector) {
                        el = el[0];
                        var matches = Element.matches || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector;
                        while ((el = el.parentElement) && !matches.call(el, selector)) {}
                        return el ? angular.element(el) : angular.element(document.body);
                    }
                };
            }
        ]);
    }());
    (function() {
        'use strict';
        var mainModule = angular.module('as.sortable');
        mainModule.controller('as.sortable.sortableController', ['$scope', function($scope) {
            this.scope = $scope;
            $scope.modelValue = null;
            $scope.callbacks = null;
            $scope.type = 'sortable';
            $scope.options = {
                longTouch: false
            };
            $scope.isDisabled = false;
            $scope.insertItem = function(index, itemData) {
                if ($scope.options.allowDuplicates) {
                    $scope.modelValue.splice(index, 0, angular.copy(itemData));
                } else {
                    $scope.modelValue.splice(index, 0, itemData);
                }
            };
            $scope.removeItem = function(index) {
                var removedItem = null;
                if (index > -1) {
                    removedItem = $scope.modelValue.splice(index, 1)[0];
                }
                return removedItem;
            };
            $scope.isEmpty = function() {
                return ($scope.modelValue && $scope.modelValue.length === 0);
            };
            $scope.accept = function(sourceItemHandleScope, destScope, destItemScope) {
                return $scope.callbacks.accept(sourceItemHandleScope, destScope, destItemScope);
            };
        }]);
        mainModule.directive('asSortable',
            function() {
                return {
                    require: 'ngModel',
                    restrict: 'A',
                    scope: true,
                    controller: 'as.sortable.sortableController',
                    link: function(scope, element, attrs, ngModelController) {
                        var ngModel, callbacks;
                        ngModel = ngModelController;
                        if (!ngModel) {
                            return;
                        }
                        ngModel.$render = function() {
                            scope.modelValue = ngModel.$modelValue;
                        };
                        scope.element = element;
                        element.data('_scope', scope);
                        callbacks = {
                            accept: null,
                            orderChanged: null,
                            itemMoved: null,
                            dragStart: null,
                            dragMove: null,
                            dragCancel: null,
                            dragEnd: null
                        };
                        callbacks.accept = function(sourceItemHandleScope, destSortableScope, destItemScope) {
                            return true;
                        };
                        callbacks.orderChanged = function(event) {};
                        callbacks.itemMoved = function(event) {};
                        callbacks.dragStart = function(event) {};
                        callbacks.dragMove = angular.noop;
                        callbacks.dragCancel = function(event) {};
                        callbacks.dragEnd = function(event) {};
                        scope.$watch(attrs.asSortable, function(newVal, oldVal) {
                            angular.forEach(newVal, function(value, key) {
                                if (callbacks[key]) {
                                    if (typeof value === 'function') {
                                        callbacks[key] = value;
                                    }
                                } else {
                                    scope.options[key] = value;
                                }
                            });
                            scope.callbacks = callbacks;
                        }, true);
                        if (angular.isDefined(attrs.isDisabled)) {
                            scope.$watch(attrs.isDisabled, function(newVal, oldVal) {
                                if (!angular.isUndefined(newVal)) {
                                    scope.isDisabled = newVal;
                                }
                            }, true);
                        }
                    }
                };
            });
    }());
    (function() {
        'use strict';
        var mainModule = angular.module('as.sortable');
        mainModule.controller('as.sortable.sortableItemHandleController', ['$scope', function($scope) {
            this.scope = $scope;
            $scope.itemScope = null;
            $scope.type = 'handle';
        }]);
    
        function isParent(possibleParent, elem) {
            if (!elem || elem.nodeName === 'HTML') {
                return false;
            }
            if (elem.parentNode === possibleParent) {
                return true;
            }
            return isParent(possibleParent, elem.parentNode);
        }
        mainModule.directive('asSortableItemHandle', ['sortableConfig', '$helper', '$window', '$document', '$timeout',
            function(sortableConfig, $helper, $window, $document, $timeout) {
                return {
                    require: '^asSortableItem',
                    scope: true,
                    restrict: 'A',
                    controller: 'as.sortable.sortableItemHandleController',
                    link: function(scope, element, attrs, itemController) {
                        var dragElement,
                            placeHolder,
                            placeElement,
                            itemPosition,
                            dragItemInfo,
                            containment,
                            containerPositioning,
                            dragListen,
                            scrollableContainer,
                            dragStart,
                            dragMove,
                            dragEnd,
                            dragCancel,
                            isDraggable,
                            placeHolderIndex,
                            bindDrag,
                            unbindDrag,
                            bindEvents,
                            unBindEvents,
                            hasTouch,
                            isIOS,
                            longTouchStart,
                            longTouchCancel,
                            longTouchTimer,
                            dragHandled,
                            createPlaceholder,
                            isPlaceHolderPresent,
                            isDisabled = false,
                            escapeListen;
                        hasTouch = 'ontouchstart' in $window;
                        isIOS = /iPad|iPhone|iPod/.test($window.navigator.userAgent) && !$window.MSStream;
                        if (sortableConfig.handleClass) {
                            element.addClass(sortableConfig.handleClass);
                        }
                        scope.itemScope = itemController.scope;
                        element.data('_scope', scope);
                        scope.$watch('sortableScope.isDisabled', function(newVal) {
                            if (isDisabled !== newVal) {
                                isDisabled = newVal;
                                if (isDisabled) {
                                    unbindDrag();
                                } else {
                                    bindDrag();
                                }
                            }
                        });
                        scope.$watch('sortableScope.options.longTouch', function() {
                            unbindDrag();
                            bindDrag();
                        });
                        scope.$on('$destroy', function() {
                            angular.element($document[0].body).unbind('keydown', escapeListen);
                        });
                        createPlaceholder = function(itemScope) {
                            if (typeof scope.sortableScope.options.placeholder === 'function') {
                                return angular.element(scope.sortableScope.options.placeholder(itemScope));
                            } else if (typeof scope.sortableScope.options.placeholder === 'string') {
                                return angular.element(scope.sortableScope.options.placeholder);
                            } else {
                                return angular.element($document[0].createElement(itemScope.element.prop('tagName')));
                            }
                        };
                        dragListen = function(event) {
                            event.preventDefault();
                            var unbindMoveListen = function() {
                                angular.element($document).unbind('mousemove', moveListen);
                                angular.element($document).unbind('touchmove', moveListen);
                                element.unbind('mouseup', unbindMoveListen);
                                element.unbind('touchend', unbindMoveListen);
                                element.unbind('touchcancel', unbindMoveListen);
                            };
                            var startPosition;
                            var moveListen = function(e) {
                                e.preventDefault();
                                var eventObj = $helper.eventObj(e);
                                if (!startPosition) {
                                    startPosition = {
                                        clientX: eventObj.clientX,
                                        clientY: eventObj.clientY
                                    };
                                }
                                if (Math.abs(eventObj.clientX - startPosition.clientX) + Math.abs(eventObj.clientY - startPosition.clientY) > 10) {
                                    unbindMoveListen();
                                    dragStart(event);
                                }
                            };
                            angular.element($document).bind('mousemove', moveListen);
                            angular.element($document).bind('touchmove', moveListen);
                            element.bind('mouseup', unbindMoveListen);
                            element.bind('touchend', unbindMoveListen);
                            element.bind('touchcancel', unbindMoveListen);
                            event.stopPropagation();
                        };
                        dragStart = function(event) {
                            var eventObj, tagName;
                            if (!hasTouch && (event.button === 2 || event.which === 3)) {
                                return;
                            }
                            if (hasTouch && $helper.isTouchInvalid(event)) {
                                return;
                            }
                            if (dragHandled || !isDraggable(event)) {
                                return;
                            }
                            dragHandled = true;
                            event.preventDefault();
                            eventObj = $helper.eventObj(event);
                            scope.sortableScope = scope.sortableScope || scope.itemScope.sortableScope;
                            scope.callbacks = scope.callbacks || scope.itemScope.callbacks;
                            if (scope.itemScope.sortableScope.options.clone || (scope.itemScope.sortableScope.options.ctrlClone && event.ctrlKey)) {
                                scope.itemScope.sortableScope.cloning = true;
                            } else {
                                scope.itemScope.sortableScope.cloning = false;
                            }
                            scrollableContainer = angular.element($document[0].querySelector(scope.sortableScope.options.scrollableContainer)).length > 0 ?
                                $document[0].querySelector(scope.sortableScope.options.scrollableContainer) : $document[0].documentElement;
                            containment = (scope.sortableScope.options.containment) ? $helper.findAncestor(element, scope.sortableScope.options.containment) : angular.element($document[0].body);
                            containment.css('cursor', 'move');
                            containment.css('cursor', '-webkit-grabbing');
                            containment.css('cursor', '-moz-grabbing');
                            containment.addClass('as-sortable-un-selectable');
                            containerPositioning = scope.sortableScope.options.containerPositioning || 'absolute';
                            dragItemInfo = $helper.dragItem(scope);
                            tagName = scope.itemScope.element.prop('tagName');
                            dragElement = angular.element($document[0].createElement(scope.sortableScope.element.prop('tagName')))
                                .addClass(scope.sortableScope.element.attr('class')).addClass(sortableConfig.dragClass);
                            dragElement.css('width', $helper.width(scope.itemScope.element) + 'px');
                            dragElement.css('height', $helper.height(scope.itemScope.element) + 'px');
                            placeHolder = createPlaceholder(scope.itemScope)
                                .addClass(sortableConfig.placeHolderClass).addClass(scope.sortableScope.options.additionalPlaceholderClass);
                            placeHolder.css('width', $helper.width(scope.itemScope.element) + 'px');
                            placeHolder.css('height', $helper.height(scope.itemScope.element) + 'px');
                            placeElement = angular.element($document[0].createElement(tagName));
                            if (sortableConfig.hiddenClass) {
                                placeElement.addClass(sortableConfig.hiddenClass);
                            }
                            itemPosition = $helper.positionStarted(eventObj, scope.itemScope.element, scrollableContainer);
                            if (!scope.itemScope.sortableScope.options.clone) {
                                scope.itemScope.element.after(placeHolder);
                            }
                            if (scope.itemScope.sortableScope.cloning) {
                                dragElement.append(scope.itemScope.element.clone());
                            } else {
                                scope.itemScope.element.after(placeElement);
                                dragElement.append(scope.itemScope.element);
                            }
                            containment.append(dragElement);
                            $helper.movePosition(eventObj, dragElement, itemPosition, containment, containerPositioning, scrollableContainer);
                            scope.sortableScope.$apply(function() {
                                scope.callbacks.dragStart(dragItemInfo.eventArgs());
                            });
                            bindEvents();
                        };
                        isDraggable = function(event) {
                            var elementClicked, sourceScope, isDraggable;
                            elementClicked = angular.element(event.target);
                            sourceScope = fetchScope(elementClicked);
                            isDraggable = (sourceScope && sourceScope.type === 'handle');
                            while (isDraggable && elementClicked[0] !== element[0]) {
                                if ($helper.noDrag(elementClicked)) {
                                    isDraggable = false;
                                }
                                elementClicked = elementClicked.parent();
                            }
                            return isDraggable;
                        };
    
                        function insertBefore(targetElement, targetScope) {
                            if (placeHolder.css('display') !== 'table-row') {
                                placeHolder.css('display', 'block');
                            }
                            if (!targetScope.sortableScope.options.clone) {
                                targetElement[0].parentNode.insertBefore(placeHolder[0], targetElement[0]);
                                dragItemInfo.moveTo(targetScope.sortableScope, targetScope.index());
                            }
                        }
    
                        function insertAfter(targetElement, targetScope) {
                            if (placeHolder.css('display') !== 'table-row') {
                                placeHolder.css('display', 'block');
                            }
                            if (!targetScope.sortableScope.options.clone) {
                                targetElement.after(placeHolder);
                                dragItemInfo.moveTo(targetScope.sortableScope, targetScope.index() + 1);
                            }
                        }
                        dragMove = function(event) {
                            var eventObj, targetX, targetY, targetScope, targetElement;
                            if (hasTouch && $helper.isTouchInvalid(event)) {
                                return;
                            }
                            if (!dragHandled) {
                                return;
                            }
                            if (dragElement) {
                                event.preventDefault();
                                eventObj = $helper.eventObj(event);
                                if (scope.callbacks.dragMove !== angular.noop) {
                                    scope.sortableScope.$apply(function() {
                                        scope.callbacks.dragMove(itemPosition, containment, eventObj);
                                    });
                                }
                                targetX = eventObj.pageX - $document[0].documentElement.scrollLeft;
                                targetY = eventObj.pageY - ($window.pageYOffset || $document[0].documentElement.scrollTop);
                                targetElement = angular.element($document[0].elementFromPoint(targetX, targetY));
                                dragElement.addClass(sortableConfig.hiddenClass);
                                dragElement.removeClass(sortableConfig.hiddenClass);
                                $helper.movePosition(eventObj, dragElement, itemPosition, containment, containerPositioning, scrollableContainer);
                                dragElement.addClass(sortableConfig.dragging);
                                targetScope = fetchScope(targetElement);
                                if (!targetScope || !targetScope.type) {
                                    return;
                                }
                                if (targetScope.type === 'handle') {
                                    targetScope = targetScope.itemScope;
                                }
                                if (targetScope.type !== 'item' && targetScope.type !== 'sortable') {
                                    return;
                                }
                                if (targetScope.type === 'item' && targetScope.accept(scope, targetScope.sortableScope, targetScope)) {
                                    targetElement = targetScope.element;
                                    var targetElementOffset = $helper.offset(targetElement, scrollableContainer);
                                    if (!dragItemInfo.canMove(itemPosition, targetElement, targetElementOffset)) {
                                        return;
                                    }
                                    var placeholderIndex = placeHolderIndex(targetScope.sortableScope.element);
                                    if (placeholderIndex < 0) {
                                        insertBefore(targetElement, targetScope);
                                    } else {
                                        if (placeholderIndex <= targetScope.index()) {
                                            insertAfter(targetElement, targetScope);
                                        } else {
                                            insertBefore(targetElement, targetScope);
                                        }
                                    }
                                }
                                if (targetScope.type === 'sortable') {
                                    if (targetScope.accept(scope, targetScope) &&
                                        !isParent(targetScope.element[0], targetElement[0])) {
                                        if (!isPlaceHolderPresent(targetElement) && !targetScope.options.clone) {
                                            targetElement[0].appendChild(placeHolder[0]);
                                            dragItemInfo.moveTo(targetScope, targetScope.modelValue.length);
                                        }
                                    }
                                }
                            }
                        };
    
                        function fetchScope(element) {
                            var scope;
                            while (!scope && element.length) {
                                scope = element.data('_scope');
                                if (!scope) {
                                    element = element.parent();
                                }
                            }
                            return scope;
                        }
                        placeHolderIndex = function(targetElement) {
                            var itemElements, i;
                            if (targetElement.hasClass(sortableConfig.placeHolderClass)) {
                                return 0;
                            }
                            itemElements = targetElement.children();
                            for (i = 0; i < itemElements.length; i += 1) {
                                if (angular.element(itemElements[i]).hasClass(sortableConfig.placeHolderClass)) {
                                    return i;
                                }
                            }
                            return -1;
                        };
                        isPlaceHolderPresent = function(targetElement) {
                            return placeHolderIndex(targetElement) >= 0;
                        };
    
                        function rollbackDragChanges() {
                            if (!scope.itemScope.sortableScope.cloning) {
                                placeElement.replaceWith(scope.itemScope.element);
                            }
                            placeHolder.remove();
                            dragElement.remove();
                            dragElement = null;
                            dragHandled = false;
                            containment.css('cursor', '');
                            containment.removeClass('as-sortable-un-selectable');
                        }
                        dragEnd = function(event) {
                            if (!dragHandled) {
                                return;
                            }
                            event.preventDefault();
                            if (dragElement) {
                                rollbackDragChanges();
                                dragItemInfo.apply();
                                scope.sortableScope.$apply(function() {
                                    if (dragItemInfo.isSameParent()) {
                                        if (dragItemInfo.isOrderChanged()) {
                                            scope.callbacks.orderChanged(dragItemInfo.eventArgs());
                                        }
                                    } else {
                                        scope.callbacks.itemMoved(dragItemInfo.eventArgs());
                                    }
                                });
                                scope.sortableScope.$apply(function() {
                                    scope.callbacks.dragEnd(dragItemInfo.eventArgs());
                                });
                                dragItemInfo = null;
                            }
                            unBindEvents();
                        };
                        dragCancel = function(event) {
                            if (!dragHandled) {
                                return;
                            }
                            event.preventDefault();
                            if (dragElement) {
                                rollbackDragChanges();
                                scope.sortableScope.$apply(function() {
                                    scope.callbacks.dragCancel(dragItemInfo.eventArgs());
                                });
                                dragItemInfo = null;
                            }
                            unBindEvents();
                        };
                        bindDrag = function() {
                            if (hasTouch) {
                                if (scope.sortableScope.options.longTouch) {
                                    if (isIOS) {
                                        element.bind('touchstart', longTouchStart);
                                        element.bind('touchend', longTouchCancel);
                                        element.bind('touchmove', longTouchCancel);
                                    } else {
                                        element.bind('contextmenu', dragListen);
                                    }
                                } else {
                                    element.bind('touchstart', dragListen);
                                }
                            } else {
                                element.bind('mousedown', dragListen);
                            }
                        };
                        unbindDrag = function() {
                            element.unbind('touchstart', longTouchStart);
                            element.unbind('touchend', longTouchCancel);
                            element.unbind('touchmove', longTouchCancel);
                            element.unbind('contextmenu', dragListen);
                            element.unbind('touchstart', dragListen);
                            element.unbind('mousedown', dragListen);
                        };
                        longTouchStart = function(event) {
                            longTouchTimer = $timeout(function() {
                                dragListen(event);
                            }, 500);
                        };
                        longTouchCancel = function() {
                            $timeout.cancel(longTouchTimer);
                        };
                        escapeListen = function(event) {
                            if (event.keyCode === 27) {
                                dragCancel(event);
                            }
                        };
                        angular.element($document[0].body).bind('keydown', escapeListen);
                        bindEvents = function() {
                            angular.element($document).bind('touchmove', dragMove);
                            angular.element($document).bind('touchend', dragEnd);
                            angular.element($document).bind('touchcancel', dragCancel);
                            angular.element($document).bind('mousemove', dragMove);
                            angular.element($document).bind('mouseup', dragEnd);
                        };
                        unBindEvents = function() {
                            angular.element($document).unbind('touchend', dragEnd);
                            angular.element($document).unbind('touchcancel', dragCancel);
                            angular.element($document).unbind('touchmove', dragMove);
                            angular.element($document).unbind('mouseup', dragEnd);
                            angular.element($document).unbind('mousemove', dragMove);
                        };
                    }
                };
            }
        ]);
    }());
    (function() {
        'use strict';
        var mainModule = angular.module('as.sortable');
        mainModule.controller('as.sortable.sortableItemController', ['$scope', function($scope) {
            this.scope = $scope;
            $scope.sortableScope = null;
            $scope.modelValue = null;
            $scope.type = 'item';
            $scope.index = function() {
                return $scope.$index;
            };
            $scope.itemData = function() {
                return $scope.sortableScope.modelValue[$scope.$index];
            };
        }]);
        mainModule.directive('asSortableItem', ['sortableConfig',
            function(sortableConfig) {
                return {
                    require: ['^asSortable', '?ngModel'],
                    restrict: 'A',
                    controller: 'as.sortable.sortableItemController',
                    link: function(scope, element, attrs, ctrl) {
                        var sortableController = ctrl[0];
                        var ngModelController = ctrl[1];
                        if (sortableConfig.itemClass) {
                            element.addClass(sortableConfig.itemClass);
                        }
                        scope.sortableScope = sortableController.scope;
                        if (ngModelController) {
                            ngModelController.$render = function() {
                                scope.modelValue = ngModelController.$modelValue;
                            };
                        } else {
                            scope.modelValue = sortableController.scope.modelValue[scope.$index];
                        }
                        scope.element = element;
                        element.data('_scope', scope);
                    }
                };
            }
        ]);
    }());;;
    /*! RESOURCE: /scripts/js_includes_sp_core.js */
    /*! RESOURCE: /scripts/app.$sp/app.$sp.js */
    angular.module("sn.$sp", [
        'oc.lazyLoad',
        'ngAnimate',
        'sn.common',
        'ngResource',
        'ngCookies',
        'sn.base',
        'ui.bootstrap',
        'sn.common.attachments',
        'sn.common.util',
        'sn.common.presence',
        'snm.auth.data',
        'snm.cabrillo',
        'snm.serviceCatalog.form',
        'snm.serviceCatalog.data',
        'sn.common.form',
        'sn.common.controls',
        'ui.tinymce',
        'ngSanitize',
        'as.sortable',
        'sp.dependencies',
        '720kb.tooltips'
    ]);
    angular.module('snm.auth.data').provider('glideSystemProperties', function glideSystemPropertiesProvider() {
        'use strict';
        var systemPropertyCache = {};
        this.$get = function glideSystemProperties($window) {
            return {
                set: function(key, value) {
                    systemPropertyCache[key] = value;
                },
                get: function(key) {
                    return systemPropertyCache[key];
                }
            };
        };
    });;
    /*! RESOURCE: /scripts/app.$sp/directive.spFormField.js */
    angular.module('sn.$sp').directive('spFormField', function($location, glideFormFieldFactory, $timeout) {
        'use strict';
        return {
            restrict: 'E',
            templateUrl: 'sp_form_field.xml',
            replace: true,
            scope: {
                field: '=',
                formModel: '=',
                getGlideForm: '&glideForm'
            },
            controller: function($element, $scope) {
                var field = $scope.field;
                if (!field)
                    throw "spFormField used without providing a field.";
                extendField($scope.field);
    
                function extendField(field) {
                    var glideField = glideFormFieldFactory.create(field);
                    field.isReadonly = glideField.isReadonly;
                    field.isMandatory = function() {
                        return !glideField.isReadonly() && glideField.isMandatory();
                    };
                    field.mandatory_filled = hasValue;
                    field.stagedValue = field.value;
                    $scope.getGlideForm().$private.events.on("change", function(fieldName, oldValue, newValue) {
                        if (fieldName == field.name)
                            field.stagedValue = newValue;
                    });
                }
    
                function hasValue() {
                    if (field.type === "boolean")
                        return true;
                    if (field.stagedValue == null || typeof field.stagedValue === 'undefined')
                        return false;
                    var trimmed = String(field.stagedValue).trim();
                    return trimmed.length > 0;
                }
                $scope.stagedValueChange = function() {
                    $scope.$emit('sp.spFormField.stagedValueChange', null);
                }
                $scope.fieldValue = function(newValue, displayValue) {
                    if (angular.isDefined(newValue)) {
                        $scope.getGlideForm().setValue(field.name, newValue, displayValue);
                    }
                    return field.value;
                };
                $scope.getEncodedRecordValues = function() {
                    var result = {};
                    angular.forEach($scope.formModel._fields, function(f) {
                        if (f.type != 'user_image')
                            result[f.name] = f.value;
                        else if (f.value)
                            result[f.name] = 'data:image/jpeg;base64,A==';
                    });
                    return result;
                };
                $scope.onImageUpload = function(thumbnail) {
                    $scope.getGlideForm().setValue(field.name, thumbnail, thumbnail);
                };
                $scope.onImageDelete = function() {
                    $scope.getGlideForm().setValue(field.name, '');
                };
                $scope.hasValueOrFocus = function() {
                    var val = $scope.hasFocus || glideFormFieldFactory.hasValue(field);
                    if (field.type == "user_image")
                        val = true;
                    return val;
                };
            },
            link: function(scope, element, attr) {
                $timeout(function() {
                    var inputField;
                    switch (scope.field.type) {
                        case "masked":
                        case "email":
                        case "password":
                            inputField = element.find("input[name='" + scope.field.name + "']");
                            break;
                        case "field_list":
                        case "glide_list":
                        case "reference":
                        case "field_name":
                        case "table_name":
                            return;
                            break;
                        default:
                            inputField = element.find("[name='" + scope.field.name + "']");
                            break;
                    }
                    var focusHandler = function() {
                        scope.hasFocus = true;
                        scope.$emit("sp.spFormField.focus", element, inputField);
                        if (!scope.$root.$$phase)
                            scope.$apply();
                    };
                    var blurHandler = function() {
                        scope.fieldValue(scope.field.stagedValue);
                        scope.hasFocus = false;
                        scope.$emit("sp.spFormField.blur", element, inputField);
                        if (!scope.$root.$$phase)
                            scope.$apply();
                    };
                    inputField.on('focus', focusHandler).on('blur', blurHandler);
                    scope.$on('$destroy', function() {
                        inputField.off('focus', focusHandler).off('blur', blurHandler);
                    });
                    scope.$emit("sp.spFormField.rendered", element, inputField);
                });
                scope.$on('select2.ready', function(e, $el) {
                    e.stopPropagation();
                    var focusHandler = function(e) {
                        $el.select2('open');
                    };
                    $el.on('focus', focusHandler);
                    scope.$on('$destroy', function() {
                        $el.off('focus', focusHandler);
                    });
                    scope.$emit("sp.spFormField.rendered", element, $el);
                });
            }
        }
    });;
    /*! RESOURCE: /scripts/app.$sp/service.spUtil.js */
    angular.module('sn.$sp').factory('spUtil', function(nowServer, $rootScope, $http, $location, snRecordWatcher, $q) {
        "use strict";
        var spUtil = {
            format: function(tpl, data) {
                var re = /{([^}]+)?}/g,
                    match;
                while (match = new RegExp(re).exec(tpl)) {
                    tpl = tpl.replace(match[0], data[match[1]]);
                }
                return tpl;
            },
            update: function($scope) {
                var s = $scope;
                return this.get(s, s.data).then(function(response) {
                    if (!response)
                        return {};
                    angular.extend(s.data, response.data);
                    return response.data;
                })
            },
            refresh: function($scope) {
                var s = $scope;
                return this.get(s, null).then(function(response) {
                    angular.extend(s.options, response.options);
                    angular.extend(s.data, response.data);
                    return response;
                })
            },
            triggerTableUIAction: function(action, table, recordID) {
                var req = {
                    method: "POST",
                    url: "/api/now/sp/uiaction/" + action.id,
                    headers: this.getHeaders(),
                    data: {
                        table: table,
                        recordID: recordID
                    }
                };
                return $http(req).then(qs, qe);
    
                function qs(response) {
                    var r = response.data.result;
                    if (r && r.$$uiNotification)
                        $rootScope.$broadcast("$$uiNotification", r.$$uiNotification);
                    return r;
                }
    
                function qe(error) {
                    console.log("Error " + error.status + " " + error.statusText);
                }
            },
            get: function($scope, data) {
                var defer = $q.defer();
                var t = this.getWidgetURL($scope);
                var req = {
                    method: 'POST',
                    url: t,
                    headers: this.getHeaders(),
                    data: data
                };
                $http(req).then(qs, qe);
    
                function qs(response) {
                    var r = response.data.result;
                    if (r && r._server_time) {
                        var w = $scope.widget;
                        if (w)
                            w._server_time = r._server_time;
                    }
                    if (r && r.$$uiNotification) {
                        if ($scope.$emit)
                            $scope.$emit("$$uiNotification", r.$$uiNotification);
                        else
                            $rootScope.$broadcast("$$uiNotification", r.$$uiNotification);
                    }
                    defer.resolve(r);
                }
    
                function qe(error) {
                    console.log("Error " + error.status + " " + error.statusText);
                    defer.reject(error);
                }
                return defer.promise;
            },
            getHeaders: function() {
                return {
                    'Accept': 'application/json',
                    'x-portal': $rootScope.portal_id
                };
            },
            getWidgetURL: function(arg) {
                if (typeof arg == 'string')
                    return "/api/now/sp/widget/" + arg;
                else if (arg.widget && arg.widget.rectangle_id)
                    return "/api/now/sp/rectangle/" + arg.widget.rectangle_id;
                else
                    return "/api/now/sp/widget/" + arg.widget.sys_id;
            },
            setBreadCrumb: function($scope, list) {
                $scope.$emit('sp.update.breadcrumbs', list);
            },
            setSearchPage: function(searchPage) {
                $rootScope.$emit("update.searchpage", searchPage);
            },
            addTrivialMessage: function(message) {
                $rootScope.$broadcast("$$uiNotification", {
                    type: "trivial",
                    message: message
                });
            },
            addInfoMessage: function(message) {
                $rootScope.$broadcast("$$uiNotification", {
                    type: "info",
                    message: message
                });
            },
            addErrorMessage: function(message) {
                $rootScope.$broadcast("$$uiNotification", {
                    type: "error",
                    message: message
                });
            },
            getURL: function(type) {
                var dataURL = nowServer.getURL("$sp");
                var n = {
                    sysparm_ck: g_ck,
                    type: type
                };
                Object.keys(n).forEach(function(t) {
                    dataURL += "&" + t + "=" + n[t]
                });
                return dataURL;
            },
            getHost: function() {
                var host = $location.protocol() + '://' + $location.host();
                if ($location.port()) {
                    host += ':' + $location.port();
                }
                return host;
            },
            scrollTo: function(id, time) {
                var t = time || 1000;
                var offset = $('.navbar').height() || 0;
                $('section').animate({
                    scrollTop: $(id).offset().top - offset - 10
                }, t);
            },
            getAccelerator: function(char) {
                var t = "";
                if (typeof window.ontouchstart == "undefined") {
                    if (navigator.userAgent.indexOf("Mac OS X") > -1)
                        t = "⌘ + " + char;
                    else
                        t = "Ctrl + " + char;
                }
                return t;
            },
            recordWatch: function($scope, table, filter, callback) {
                filter = filter || 'sys_id!=-1';
                var watcherChannel = snRecordWatcher.initChannel(table, filter);
                var deregister = $scope.$on('record.updated', function(name, data) {
                    if (data.table_name != table)
                        return;
                    if (callback)
                        callback(name, data);
                    else
                        $scope.server.update();
                })
                $scope.$on('$destroy', function() {
                    deregister();
                    watcherChannel.unsubscribe();
                })
            },
            createUid: function(str) {
                return str.replace(/[xy]/g, function(c) {
                    var r, v;
                    r = Math.random() * 16 | 0;
                    v = c === 'x' ? r : r & 0x3 | 0x8;
                    return v.toString(16);
                });
            }
        }
        return spUtil;
    });
    /*! RESOURCE: /scripts/app.$sp/directive.spCatItem.js */
    angular.module("sn.$sp").directive('spCatItem', function($http, spUtil, $rootScope) {
        return {
            restrict: 'E',
            link: function(scope, element, attrs) {
                scope.item = scope.$eval(attrs.item);
            },
            controller: function($scope) {
                $scope.$on('variable.price.change', function(evt, parms) {
                    var p = $scope.item._pricing;
                    var changed = false;
                    var t = parms.recurring_price + p.recurring_price;
                    if (t != p.recurring_total) {
                        changed = true;
                        p.recurring_total = t;
                    }
                    t = parms.price + p.price
                    if (t != p.price_total) {
                        changed = true;
                        p.price_total = parms.price + p.price;
                    }
                    if (!changed)
                        return;
                    var o = {
                        price: p.price_total,
                        recurring_price: p.recurring_total
                    };
                    $rootScope.$broadcast("guide.item.price.change", o);
                    $http.post(spUtil.getURL('format_prices'), o).success(function(response) {
                        var t = $scope.data.sc_cat_item;
                        t = $scope.item;
                        t.price = t.recurring_price = "";
                        if (p.price_total)
                            t.price = response.price;
                        if (p.recurring_total)
                            t.recurring_price = response.recurring_price + " " + p.rfd;
                    })
                })
            }
        }
    });
    /*! RESOURCE: /scripts/app.$sp/directive.spChoiceList.js */
    angular.module('sn.$sp').directive('spChoiceList', function($timeout, urlTools, $http) {
        var ChoiceType = {
            DropdownWithNone: 1,
            DropdownWithoutNone: 3
        };
        return {
            template: '<select name="{{field.name}}" ng-model="fieldValue" ng-model-options="{getterSetter: true}" sn-select-width="auto" ng-disabled="field.isReadonly()" ng-options="c.value as c.label for c in field.choices track by getVal(c.value)"></select>',
            restrict: 'E',
            replace: true,
            require: 'ngModel',
            scope: {
                'field': '=',
                'options': '=?',
                'getGlideForm': '&glideForm'
            },
            link: function(scope, element, attrs, ngModel) {
                scope.getVal = function(v) {
                    return v;
                };
                var g_form = scope.getGlideForm();
                var field = scope.field;
                var fieldOptions;
                scope.fieldValue = function() {
                    return field.value;
                };
                g_form.$private.events.on('change', function(fieldName, oldValue, newValue) {
                    if (fieldName == field.name) {} else if (fieldName == field.dependentField) {
                        field.dependentValue = newValue;
                        refreshChoiceList();
                    } else if ('variable_name' in field && field.reference_qual && field.reference_qual.indexOf(fieldName) != -1) {
                        refreshReferenceChoices();
                    }
                });
    
                function refreshChoiceList() {
                    var params = {};
                    params.table = g_form.getTableName();
                    params.field = field.name;
                    params.sysparm_dependent_value = field.dependentValue;
                    var url = urlTools.getURL('choice_list_data', params);
                    return $http.get(url).success(function(data) {
                        field.choices = [];
                        angular.forEach(data.items, function(item) {
                            field.choices.push(item);
                        });
                        selectValueOrNone();
                    });
                }
    
                function selectValueOrNone() {
                    var hasSelectedValue = false;
                    angular.forEach(field.choices, function(c) {
                        if (field.value == c.value)
                            hasSelectedValue = true;
                    });
                    if (!hasSelectedValue && field.choices.length > 0 && (field.choice == ChoiceType.DropdownWithNone || field.choice == ChoiceType.DropdownWithoutNone))
                        g_form.setValue(field.name, field.choices[0].value, field.choices[0].label);
                }
    
                function refreshReferenceChoices() {
                    var params = [];
                    params['qualifier'] = field.reference_qual;
                    params['table'] = field.lookup_table;
                    params['sysparm_include_variables'] = true;
                    params['variable_ids'] = field.sys_id;
                    var getFieldSequence = g_form.$private.options('getFieldSequence');
                    if (getFieldSequence) {
                        params['variable_sequence1'] = getFieldSequence();
                    }
                    var itemSysId = g_form.$private.options('itemSysId');
                    params['sysparm_id'] = itemSysId;
                    var getFieldParams = g_form.$private.options('getFieldParams');
                    if (getFieldParams) {
                        angular.extend(params, getFieldParams());
                    }
                    var url = urlTools.getURL('sp_ref_list_data', params);
                    return $http.get(url).success(function(data) {
                        var hasSelectedValue = false;
                        field.choices = [];
                        angular.forEach(data.items, function(item) {
                            item.label = item.$$displayValue;
                            item.value = item.sys_id;
                            if (field.value == item.value)
                                hasSelectedValue = true;
                            field.choices.push(item);
                        });
                        if (!hasSelectedValue && field.choices.length > 0)
                            g_form.setValue(field.name, field.choices[0].value, field.choices[0].label);
                    });
                }
                var pcTimeout;
                g_form.$private.events.on('propertyChange', function(type, fieldName, propertyName) {
                    if (fieldName != field.name)
                        return;
                    if (propertyName == "optionStack") {
                        $timeout.cancel(pcTimeout);
                        pcTimeout = $timeout(function() {
                            field.choices = applyOptionStack(fieldOptions, field.optionStack);
                            selectValueOrNone();
                        }, 35);
                    }
                });
                setDefaultOptions();
                if (field.choices) {
                    setChoiceOptions(field.choices);
                }
                selectValueOrNone();
    
                function setDefaultOptions() {
                    setChoiceOptions([{
                        value: scope.field.value,
                        label: scope.field.displayValue || scope.field.placeholder
                    }]);
                }
    
                function setChoiceOptions(options) {
                    if (options) {
                        options.forEach(function(option) {
                            option.value = String(option.value);
                        });
                    }
                    fieldOptions = options;
                    scope.options = applyOptionStack(options, scope.field.optionStack);
                }
    
                function removeDuplicateNone() {
                    var childrenOpt = element[0].children;
                    if (childrenOpt.length == 0)
                        return;
                    var firstElement = angular.element(childrenOpt[0]);
                    if (firstElement && firstElement.val().trim() == "")
                        firstElement.remove();
                }
    
                function applyOptionStack(options, optionStack) {
                    if (!optionStack || optionStack.length == 0) {
                        return options;
                    }
                    var newOptions = angular.copy(options);
                    if (!newOptions) {
                        newOptions = [];
                    }
                    optionStack.forEach(function(item) {
                        switch (item.operation) {
                            case 'add':
                                for (var o in newOptions) {
                                    if (newOptions[o].label == item.label)
                                        return;
                                }
                                var newOption = {
                                    label: item.label,
                                    value: item.value
                                };
                                if (typeof item.index === 'undefined') {
                                    newOptions.push(newOption);
                                } else {
                                    newOptions.splice(item.index, 0, newOption);
                                }
                                removeDuplicateNone();
                                break;
                            case 'remove':
                                var itemValue = String(item.value);
                                for (var i = 0, iM = newOptions.length; i < iM; i++) {
                                    var optionValue = String(newOptions[i].value);
                                    if (optionValue !== itemValue) {
                                        continue;
                                    }
                                    newOptions.splice(i, 1);
                                    if (i == 0)
                                        removeDuplicateNone();
                                    break;
                                }
                                break;
                            case 'clear':
                                newOptions = [];
                                removeDuplicateNone();
                                break;
                            default:
                        }
                    });
                    return newOptions;
                }
                if (angular.isFunction(element.select2)) {
                    element.select2({
                        allowClear: false,
                        width: '100%'
                    });
                    element.bind("change select2-removed", function(e) {
                        e.stopImmediatePropagation();
                        if (e.added) {
                            var selectedItem = e.added;
                            g_form.setValue(field.name, selectedItem.id, selectedItem.text);
                        } else if (e.removed) {
                            g_form.clearValue(scope.field.name);
                        }
                    });
                    ngModel.$render = function() {
                        if (ngModel.$viewValue === "" || ngModel.$viewValue === null)
                            selectValueOrNone();
                        element.select2('val', ngModel.$viewValue);
                    };
                }
            }
        };
    });;
    /*! RESOURCE: /scripts/app.$sp/directive.spCLink.js */
    angular.module('sn.$sp').directive('spCLink', function(i18n) {
        return {
            restrict: 'E',
            scope: {
                rectangle: '=',
                target: '@',
                table: '=',
                id: '=',
                query: '='
            },
            replace: true,
            template: '<span class="sp-convenience-link-wrapper" ng-if="display()"><a href="{{href}}" target="_blank" class="sp-convenience-link">{{getText()}}</a></span>',
            link: function(scope, element, attrs, controller) {
                scope.display = function() {
                    return scope.href && window.NOW.sp_debug;
                }
                var href = '';
                if (scope.target) {
                    var target = scope.target;
                    if (target == 'form')
                        href = scope.table + '.do?sys_id=' + scope.id;
                    if (target == 'kb_article')
                        href = 'kb_view.do?sysparm_article=' + scope.id;
                    if (target == 'sc_cat_item')
                        href = 'com.glideapp.servicecatalog_cat_item_view.do?sysparm_id=' + scope.id + '&sysparm_catalog_view=catalog_default';
                    if (target == 'list') {
                        scope.$watch(function() {
                            return scope.table + " | " + scope.query;
                        }, function(newValue, oldValue) {
                            if (newValue != oldValue)
                                scope.href = scope.table + '_list.do?sysparm_query=' + scope.query;
                        })
                        href = scope.table + '_list.do?sysparm_query=' + scope.query;
                    }
                }
                scope.href = href;
                scope.getText = function() {
                    return i18n.getMessage('Open');
                }
            }
        }
    });
    /*! RESOURCE: /scripts/app.$sp/service.spCommunicator.js */
    angular.module('sn.$sp').factory('spCommunicator', ['$rootScope', function($rootScope) {
        return {
            deregFuncMap: {},
            _getEventMap: function($scope) {
                var eventMap = this.deregFuncMap[$scope.$id];
                if (!eventMap)
                    eventMap = this.deregFuncMap[$scope.$id] = {};
                return eventMap;
            },
            start: function(event, handler, $scope) {
                this.stop(event, $scope);
                var eventMap = this._getEventMap($scope);
                eventMap[event] = $rootScope.$on(event, function(event, data) {
                    handler(data);
                });
            },
            stop: function(event, $scope) {
                var eventMap = this._getEventMap($scope);
                var deregFunc = eventMap[event];
                if (deregFunc)
                    deregFunc();
            },
            fire: function(event, data) {
                if (event)
                    $rootScope.$broadcast(event, data);
            }
        }
    }]);
    /*! RESOURCE: /scripts/app.$sp/directive.spDatePicker.js */
    angular.module('sn.$sp').directive('spDatePicker', function(dateUtils, $rootScope) {
        var dateFormat = g_user_date_format || dateUtils.SYS_DATE_FORMAT;
        if ($rootScope.user && $rootScope.user.date_format)
            dateFormat = $rootScope.user.date_format;
    
        function isValidDate(value, format) {
            if (value === '')
                return true;
            return dateUtils.getDateFromFormat(value, format) != 0;
        }
        return {
            template: '<div ng-class="{\'input-group\': !snDisabled, \'has-error\': isInvalid}" style="width: 100%;">' +
                '<input type="text" name="{{field.name}}" class="form-control" placeholder="{{field.placeholder}}" ng-model="formattedDate" ng-model-options="{updateOn: \'blur\', getterSetter: true}" ng-disabled="snDisabled" />' +
                '<span class="input-group-btn" ng-hide="snDisabled">' +
                '<input type="hidden" class="datepickerinput" ng-model="formattedDate" ng-readonly="true" />' +
                '<button class="btn btn-default" type="button">' +
                '<glyph sn-char="calendar" />' +
                '</button>' +
                '</span>' +
                '</div>',
            restrict: 'E',
            replace: true,
            require: '?ngModel',
            scope: {
                field: '=',
                snDisabled: '=',
                snIncludeTime: '=',
                snChange: '&'
            },
            link: function(scope, element, attrs, ngModel) {
                var includeTime = scope.snIncludeTime;
                var format = includeTime ? dateFormat.trim() + ' ' + dateUtils.SYS_TIME_FORMAT : dateFormat;
                var dp = element.find('.input-group-btn').datetimepicker({
                    keepInvalid: true,
                    pickTime: scope.snIncludeTime === true,
                    format: "X"
                }).on('dp.change', onDpChange);
    
                function onDpChange(e) {
                    var value = new Date(e.date._d);
                    scope.formattedDate(dateUtils.formatDate(value, format));
                    if (!scope.$root.$$phase)
                        scope.$apply();
                }
    
                function validate(formattedDate) {
                    scope.isInvalid = false;
                    if (formattedDate == null || formattedDate == '') {
                        dp.data('DateTimePicker').setValue(new Date());
                        return '';
                    }
                    if (isValidDate(formattedDate, format)) {
                        var d = dateUtils.getDateFromFormat(formattedDate, format);
                        dp.data('DateTimePicker').setValue(new Date(d));
                    } else {
                        scope.isInvalid = true;
                    }
                    return formattedDate;
                }
                if (ngModel) {
                    ngModel.$parsers.push(validate);
                    ngModel.$render = function() {
                        validate(ngModel.$viewValue);
                    };
                    scope.formattedDate = function(formattedValue) {
                        if (angular.isDefined(formattedValue)) {
                            ngModel.$setViewValue(formattedValue);
                            if (scope.snChange) scope.snChange({
                                newValue: formattedValue
                            });
                        }
                        return ngModel.$viewValue;
                    };
                } else {
                    scope.formattedDate = function(formattedValue) {
                        if (angular.isDefined(formattedValue)) {
                            scope.field.value = validate(formattedValue);
                            if (scope.snChange) scope.snChange({
                                newValue: formattedValue
                            });
                        }
                        return scope.field.value;
                    };
                    scope.$watch('field.value', function(newValue, oldValue) {
                        if (newValue != oldValue)
                            validate(newValue);
                    });
                }
                scope.$on('$destroy', function() {
                    dp.off('dp.change', onDpChange);
                });
            }
        }
    });;
    /*! RESOURCE: /scripts/app.$sp/directive.spDropdownTree.js */
    angular.module('sn.$sp').directive('spDropdownTree', function() {
        return {
            restrict: 'E',
            scope: {
                items: '='
            },
            replace: true,
            template: '<ul class="dropdown-menu">' +
                '<li ng-repeat="mi in items" style="min-width: 20em;" ng-class="{\'dropdown-submenu\': mi.type == \'menu\', \'dropdown-menu-line\':$index < items.length - 1}" ng-include="getURL()">' +
                '</ul>',
            link: function(scope, element, attrs, controller) {
                scope.getURL = function() {
                    return 'spDropdownTreeTemplate';
                }
            }
        }
    });
    (function($) {
        $("body").on("click", "a.menu_trigger", function(e) {
            var current = $(this).next();
            var grandparent = $(this).parent().parent();
            if ($(this).hasClass('left-caret') || $(this).hasClass('right-caret'))
                $(this).toggleClass('right-caret left-caret');
            grandparent.find('.left-caret').not(this).toggleClass('right-caret left-caret');
            current.toggle();
            $(".dropdown-menu").each(function(i, elem) {
                var elemClosest = $(elem).closest('.dropdown');
                var currentClosest = current.closest('.dropdown');
                if (!elem.contains(current[0]) && elem != current[0] && (!currentClosest.length || !elemClosest.length || elemClosest[0] == currentClosest[0]))
                    $(elem).hide();
            })
            e.stopPropagation();
        });
        $("body").on("click", "a:not(.menu_trigger)", function() {
            var root = $(this).closest('.dropdown');
            root.find('.left-caret').toggleClass('right-caret left-caret');
        });
    })(jQuery);;
    /*! RESOURCE: /scripts/app.$sp/factory.spMacro.js */
    angular.module('sn.$sp').factory("spMacro", function() {
        "use strict";
        return function($scope, dataPrototype, inputMap, keepFields) {
            var gf = $scope.page.g_form;
            if (!gf) {
                console.warn('GlideForm not set for widget: ' + $scope.widget.name);
                return;
            }
            var map = createMap();
    
            function createMap() {
                var names = gf.getFieldNames();
                var fields = [];
                names.forEach(function(name) {
                    fields.push(gf.getField(name));
                })
                var map = {};
                angular.forEach(inputMap, function(value, key) {
                    fields.forEach(function(field) {
                        if (field.variable_name == value) {
                            map[key] = field.name;
                            if (!keepFields)
                                gf.setDisplay(field.name, false);
                        }
                    })
                })
                angular.forEach(dataPrototype, function(value, key) {
                    if (map[key])
                        return;
                    fields.forEach(function(field) {
                        if (field.variable_name == key) {
                            map[key] = field.name;
                            if (!keepFields)
                                gf.setDisplay(field.name, false);
                        }
                    })
                })
                return map;
            }
            return {
                getMap: function() {
                    return map;
                },
                onChange: function(newV, oldV) {
                    if (!angular.isDefined(newV))
                        return;
                    angular.forEach(newV, function(value, key) {
                        if (newV[key] == oldV[key])
                            return;
                        var n = map[key];
                        gf.setValue(n, newV[key]);
                    })
                }
            }
        }
    });
    /*! RESOURCE: /scripts/app.$sp/factory.spUIActionFactory.js */
    angular.module('sn.$sp').factory('spUIActionFactory', function($http, $rootScope) {
        'use strict';
        return {
            create: function(uiActions, options) {
                return new GlideUIActions(uiActions, options);
            },
            executeUIAction: executeDesktopUIAction
        };
    
        function GlideUIActions(uiActions, options) {
            if (!uiActions) {
                throw 'uiActions must be provided';
            }
            var _uiActionsById = {};
            var _uiActions = [];
            options = options || {};
            uiActions.forEach(function(uiAction) {
                var action = new GlideUIAction(
                    uiAction.action_name,
                    uiAction.sys_id,
                    uiAction.name,
                    options.uiActionNotifier,
                    options.attachmentGUID
                );
                _uiActionsById[action.getSysId()] = action;
                _uiActions.push(action);
            });
            this.getActions = function() {
                return _uiActions;
            };
            this.getAction = function(sysId) {
                return _uiActionsById[sysId];
            };
            this.getActionByName = function(name) {
                var foundAction;
                _uiActions.forEach(function(action) {
                    if (foundAction) {
                        return;
                    }
                    if (name === action.getName()) {
                        foundAction = action;
                    }
                });
                if (!foundAction)
                    foundAction = this.getAction(name);
                return foundAction;
            };
        }
    
        function GlideUIAction(name, sysId, displayName, uiActionNotifier, attachmentGUID) {
            var _inProgress = false;
            var _name = name;
            var _displayName = displayName;
            var _sysId = sysId;
            var _notifier = uiActionNotifier;
            this.getSysId = function() {
                return _sysId;
            };
            this.getName = function() {
                return _name;
            };
            this.getDisplayName = function() {
                return _displayName;
            };
            this.execute = function(g_form) {
                _inProgress = true;
                var formData = {};
                var fieldNames = g_form.getFieldNames();
                fieldNames.forEach(function(name) {
                    formData[name] = g_form.getField(name);
                });
                if (attachmentGUID)
                    formData._attachmentGUID = attachmentGUID;
                var $execute = executeDesktopUIAction(
                    this.getSysId(),
                    g_form.getTableName(),
                    g_form.getSysId(),
                    formData
                ).finally(function() {
                    _inProgress = false;
                });
                _notifier(this.getName(), $execute);
                return $execute;
            };
        }
    
        function executeDesktopUIAction(actionSysId, tableName, recordSysId, formData) {
            var req = {
                method: "POST",
                url: "/api/now/sp/uiaction/" + actionSysId,
                headers: {
                    'Accept': 'application/json',
                    'x-portal': $rootScope.portal_id
                },
                data: {
                    table: tableName,
                    recordID: recordSysId,
                    data: formData
                }
            };
            return $http(req).then(qs, qe);
    
            function qs(response) {
                var r = response.data.result;
                if (r && r.$$uiNotification)
                    $rootScope.$broadcast("$$uiNotification", r.$$uiNotification);
                return r;
            }
    
            function qe(error) {
                console.log("Error " + error.status + " " + error.statusText);
            }
        }
    });;
    /*! RESOURCE: /scripts/app.$sp/service.spFileSelect.js */
    angular.module('sn.$sp').factory('spFileSelect', ['$rootScope', '$upload', '$timeout', function($rootScope, $upload, $timeout) {
        'use strict';
        var imageFile = {};
        return {
            onFileSelect: function($files, field) {
                imageFile[field.name] = null;
                if ($files.length == 1 && window.FileReader && $files[0].type.indexOf('image') > -1) {
                    field.image = null;
                    imageFile[field.name] = $files[0];
                    var fileReader = new FileReader();
                    fileReader.readAsDataURL(imageFile[field.name]);
                    fileReader.onload = function(e) {
                        field.value = e.target.result;
                    }
                    $upload.upload({
                        url: 'upload',
                        data: {},
                        formDataAppender: function(formData, key, val) {
                            if (angular.isArray(val))
                                angular.forEach(val, function(v) {
                                    formData.append(key, v);
                                });
                            else
                                formData.append(key, val);
                        },
                        file: imageFile[field.name],
                        fileFormDataName: 'myFile'
                    })
                }
            }
        }
    }]);
    /*! RESOURCE: /scripts/app.$sp/directive.spGlyph.js */
    angular.module('sn.$sp').directive("spGlyph", function() {
        "use strict";
        return {
            restrict: 'E',
            replace: true,
            scope: {
                char: "@",
            },
            template: '<span class="glyphicon glyphicon-{{char}}" />',
            link: function(scope) {}
        }
    });
    /*! RESOURCE: /scripts/app.$sp/directive.spGlyphPicker.js */
    angular.module('sn.$sp').directive('spGlyphPicker', function($rootScope) {
        return {
            template: '<span class="glyph-picker-container">' +
                '<button ng-show="!disabled()" class="btn btn-default" data-iconset="fontawesome" data-icon="fa-{{field.value}}" role="iconpicker" />' +
                '<div ng-show="disabled()" class="fa fa-{{field.value}} glyph-picker-disabled"/>' +
                '</span>',
            restrict: 'E',
            replace: true,
            scope: {
                field: '=',
                snOnChange: '&',
                snOnBlur: '&',
                snDisabled: '&'
            },
            link: function(scope, element, attrs, controller) {
                scope.disabled = function() {
                    if (typeof scope.snDisabled() == "undefined")
                        return false;
                    return scope.snDisabled();
                }
                var button = element.find('button');
                button.on('click', function(e) {
                    var describedByAttr = this.attributes['aria-describedby'];
                    if (describedByAttr && describedByAttr.value.startsWith("popover")) {
                        e.stopImmediatePropagation();
                    }
                });
                button.iconpicker({
                    cols: 6,
                    rows: 6,
                    placement: 'right',
                    iconset: 'fontawesome'
                });
                scope.transferIcon = function() {
                    button.iconpicker('setIcon', 'fa-' + scope.field.value);
                }
                scope.$watch(function() {
                    return scope.field.value;
                }, function(newValue, oldValue) {
                    if (newValue != oldValue)
                        scope.transferIcon();
                })
                scope.transferIcon();
                button.on('change', function(e) {
                    scope.field.value = e.icon.replace(/^fa-/, '');
                    if (!$rootScope.$$phase)
                        $rootScope.$digest();
                    scope.snOnChange();
                })
                button.on('change', function(e) {
                    scope.snOnBlur();
                })
            }
        }
    });
    /*! RESOURCE: /scripts/app.$sp/directive.spColorPicker.js */
    angular.module('sn.$sp').directive('spColorPicker', function($timeout) {
        return {
            template: '<div class="input-group">' +
                '<input class="form-control" name="{{field.name}}" value="{{field.value}}" placeholder="{{field.placeholder}}" autocomplete="off" ng-disabled="snDisabled" />' +
                '<input type="text" class="btn input-group-btn" name="color_picker_{{field.name}}" ng-disabled="snDisabled" />' +
                '</div>',
            restrict: 'E',
            replace: true,
            scope: {
                field: '=',
                getGlideForm: '&glideForm',
                snChange: "&",
                snDisabled: "="
            },
            link: function(scope, element, attrs, controller) {
                var field = scope.field;
                var initialColor;
    
                function setValue(newVal) {
                    if (!scope.snDisabled)
                        scope.snChange({
                            newValue: newVal
                        });
                }
                $timeout(function() {
                    init();
                });
    
                function init() {
                    var $input = element.find('input[name="' + field.name + '"]');
                    var $picker = element.find('input[name="color_picker_' + field.name + '"]');
                    $picker.spectrum({
                        color: field.value,
                        showInitial: true,
                        showButtons: false,
                        showInput: true,
                        showSelectionPalette: false,
                        preferredFormat: "hex",
                        showPalette: true,
                        hideAfterPaletteSelect: true,
                        replacerClassName: "input-group-btn",
                        palette: [
                            ["#000000", "#ffffff", "#343d47", "#485563", "#81878e", "#bdc0c4", "#e6e8ea"],
                            ["#e7e9eb", "#6d79eb", "#8784db", "#b1afdb", "#278efc", "#83bfff", "#c0dcfa"],
                            ["#289fdb", "#97e0fc", "#caeefc", "#71e279", "#6edb8f", "#9adbad", "#fcc742"],
                            ["#ffe366", "#fff1b2", "#fc8a3d", "#ffc266", "#ffe0b2", "#f95050", "#ff7b65"],
                            ["#ffbeb2", "#f95070", "#ff93a2", "#ffc1ca", "#cddc39", "#e6ee9c", "#f9fbe7"]
                        ],
                        show: function(color) {
                            initialColor = color.toHexString();
                        },
                        hide: function(color) {
                            var newVal = color.toHexString();
                            if (initialColor != newVal) {
                                setValue(newVal);
                            }
                        },
                        move: function(color) {
                            var newVal = color.toHexString();
                            setValue(newVal);
                        },
                        change: function(color) {
                            var newVal = color.toHexString();
                            setValue(newVal);
                        }
                    });
                    $input.on("focus", function() {
                        var el = angular.element(this);
                        initialColor = el.val();
                    });
                    $input.on("blur", function() {
                        var el = angular.element(this);
                        var newVal = el.val();
                        if (initialColor != newVal) {
                            $picker.spectrum("set", newVal);
                            setValue(newVal);
                        }
                    });
                }
            }
        }
    });
    /*! RESOURCE: /scripts/app.$sp/directive.spReferenceField.js */
    angular.module('sn.$sp').directive('spReferenceField', function($rootScope, spUtil, $uibModal, $http) {
        'use strict';
        return {
            restrict: 'E',
            replace: true,
            templateUrl: 'sp_reference_field.xml',
            controller: function($scope) {
                $scope.openReference = function(field, view) {
                    var data = {
                        table: field.ed.reference,
                        sys_id: field.value,
                        view: view
                    };
                    if (angular.isDefined(field.reference_key))
                        data[field.reference_key] = field.value;
                    else
                        data.sys_id = field.value;
                    showForm(data);
                };
    
                function showForm(data) {
                    var url = spUtil.getWidgetURL("widget-form");
                    var req = {
                        method: 'POST',
                        url: url,
                        headers: {
                            'Accept': 'application/json',
                            'x-portal': $rootScope.portal_id
                        },
                        data: data
                    }
                    $http(req).then(qs, qe);
    
                    function qs(response) {
                        var r = response.data.result;
                        showModal(r);
                    }
    
                    function qe(error) {
                        console.error("Error " + error.status + " " + error.statusText);
                    }
                }
    
                function showModal(form) {
                    var opts = {
                        size: 'lg',
                        templateUrl: 'sp_form_modal',
                        controller: ModalInstanceCtrl,
                        resolve: {}
                    };
                    opts.resolve.item = function() {
                        return angular.copy({
                            form: form
                        });
                    };
                    var modalInstance = $uibModal.open(opts);
                    modalInstance.result.then(function() {}, function() {});
                    $scope.$on("$destroy", function() {
                        modalInstance.close();
                    });
                    var unregister = $scope.$on('sp.form.record.updated', function(evt, fields) {
                        unregister();
                        unregister = null;
                        modalInstance.close();
                        if (evt.stopPropagation)
                            evt.stopPropagation();
                        evt.preventDefault();
                    });
                }
    
                function ModalInstanceCtrl($scope, $uibModalInstance, item) {
                    $scope.item = item;
                    $scope.ok = function() {
                        $uibModalInstance.close();
                    };
                    $scope.cancel = function() {
                        $uibModalInstance.dismiss('cancel');
                    };
                }
            }
        }
    });;
    /*! RESOURCE: /scripts/app.$sp/directive.spCssEditor.js */
    angular.module('sn.$sp').directive('spCssEditor', function() {
        return {
            template: '<textarea ng-model="v" name="{{::field.name}}" style="width: 100%; min-height: 2em;" rows="1" wrap="soft" data-length="{{::dataLength}}" data-charlimit="false">' +
                '</textarea>',
            restrict: 'E',
            replace: true,
            require: '^ngModel',
            scope: {
                field: '=',
                dataLength: '@',
                snDisabled: '=?',
                snChange: '&',
                snBlur: '&'
            },
            link: function(scope, element, attrs, ctrl) {
                element[0].value = scope.field.value;
                element[0].id = scope.field.name + "_css_editor";
                var cmi = CodeMirror.fromTextArea(element[0], {
                    mode: "text/x-less",
                    lineWrapping: false,
                    readOnly: scope.snDisabled === true,
                    viewportMargin: Infinity,
                    lineNumbers: true,
                    tabSize: 2
                });
                cmi.on('change', function(cm) {
                    if ("stagedValue" in scope.field) {
                        scope.field.stagedValue = cm.getValue();
                        ctrl.$setViewValue(scope.field.stagedValue);
                    } else {
                        scope.field.value = cm.getValue();
                        ctrl.$setViewValue(scope.field.value);
                    }
                    if (angular.isDefined(scope.snChange))
                        scope.snChange();
                });
                cmi.on('blur', function() {
                    if (angular.isDefined(scope.snBlur))
                        scope.snBlur();
                });
                ctrl.$viewChangeListeners.push(function() {
                    scope.$eval(attrs.ngChange);
                });
                scope.$watch(function() {
                    return scope.field.value;
                }, function(newValue, oldValue) {
                    if (newValue != oldValue && !cmi.hasFocus())
                        cmi.getDoc().setValue(scope.field.value);
                });
                scope.$watch('snDisabled', function(newValue) {
                    if (angular.isDefined(newValue)) {
                        cmi.setOption('readOnly', newValue);
                    }
                });
            }
        }
    });
    /*! RESOURCE: /scripts/app.$sp/directive.spTinymceEditor.js */
    angular.module('sn.$sp').directive('spTinymceEditor', function(getTemplateUrl, snAttachmentHandler, $timeout) {
        return {
            templateUrl: getTemplateUrl('sp_tinymce_editor.xml'),
            restrict: 'E',
            replace: true,
            scope: {
                model: "=ngModel",
                options: "=ngModelOptions",
                snBlur: '&',
                snDisabled: '=?'
            },
            controller: function($scope) {
                $scope.options = $scope.options || {};
                var thisEditor = {};
                $scope.tinyMCEOptions = {
                    skin: 'lightgray',
                    theme: 'modern',
                    menubar: false,
                    statusbar: false,
                    plugins: "codesample code",
                    toolbar: 'undo redo | formatselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | image | codesample code',
                    setup: function(ed) {
                        thisEditor = ed;
                        ed.addCommand('imageUpload', function(ui, v) {
                            $scope.clickAttachment();
                        });
                        ed.addButton('image', {
                            icon: 'image',
                            tooltip: 'Insert image',
                            onclick: function(e) {
                                ed.execCommand('imageUpload');
                            },
                            stateSelector: 'img:not([data-mce-object],[data-mce-placeholder])'
                        });
                        ed.on('blur', function() {
                            if (angular.isDefined($scope.snBlur))
                                $scope.snBlur();
                        });
                        $scope.registerPasteHandler();
                    }
                };
                $scope.attachFiles = function(data) {
                    snAttachmentHandler.create("kb_social_qa_question", "-1").uploadAttachment(data.files[0], null, {}).then(function(response) {
                        var args = tinymce.extend({}, {
                            src: encodeURI("/" + response.sys_id + ".iix"),
                            style: "max-width: 100%; max-height: 480px;"
                        });
                        thisEditor.execCommand('mceInsertContent', false, thisEditor.dom.createHTML('img', args), {
                            skip_undo: 1
                        });
                    });
                };
                $scope.$watch('snDisabled', function(newValue) {
                    if (angular.isDefined(newValue) && typeof thisEditor.setMode == "function")
                        thisEditor.setMode(newValue ? 'readonly' : 'design');
                });
            },
            link: function(scope, element, attrs) {
                scope.attrs = attrs;
                scope.clickAttachment = function() {
                    element.find("input").click();
                };
                scope.registerPasteHandler = function() {
                    $timeout(function() {
                        element.find('iframe').contents().find('body').bind('paste', function(e) {
                            e = e.originalEvent;
                            var files = [];
                            for (var i = 0; i < e.clipboardData.items.length; i++) {
                                var item = e.clipboardData.items[i];
                                if (item.kind && item.kind === "file") {
                                    var file = item.getAsFile();
                                    Object.defineProperty(file, "name", {
                                        value: "Pasted File - " + new Date()
                                    });
                                    files.push(file);
                                }
                            }
                            if (files.length > 0) {
                                e.stopPropagation();
                                e.preventDefault();
                                scope.attachFiles({
                                    files: files
                                });
                            }
                        });
                    });
                };
            }
        }
    });
    /*! RESOURCE: /scripts/app.$sp/directive.spHTMLEditor.js */
    angular.module('sn.$sp').directive('spHtmlEditor', function() {
        return {
            template: '<textarea class="CodeMirror" name="{{::field.name}}" ng-model="v" style="width: 100%;" data-length="{{ ::dataLength }}" data-charlimit="false"></textarea>',
            restrict: 'E',
            require: '^ngModel',
            replace: true,
            scope: {
                field: '=',
                dataLength: '@',
                rows: '@',
                snDisabled: '=?',
                snChange: '&',
                snBlur: '&'
            },
            link: function(scope, element, attrs, ctrl) {
                element[0].value = scope.field.value;
                element[0].id = scope.field.name + "_html_editor";
                var cmi = CodeMirror.fromTextArea(element[0], {
                    mode: "htmlmixed",
                    lineWrapping: false,
                    readOnly: scope.snDisabled === true,
                    viewportMargin: Infinity,
                    lineNumbers: true,
                    tabSize: 2
                });
                ctrl.$viewChangeListeners.push(function() {
                    scope.$eval(attrs.ngChange);
                });
                cmi.on('change', function(cm) {
                    if ("stagedValue" in scope.field) {
                        scope.field.stagedValue = cm.getValue();
                        ctrl.$setViewValue(scope.field.stagedValue);
                    } else {
                        scope.field.value = cm.getValue();
                        ctrl.$setViewValue(scope.field.value);
                    }
                    if (angular.isDefined(scope.snChange))
                        scope.snChange();
                });
                cmi.on('blur', function() {
                    if (angular.isDefined(scope.snBlur))
                        scope.snBlur();
                });
                scope.$watch(function() {
                    return scope.field.value;
                }, function(newValue, oldValue) {
                    if (newValue != oldValue && !cmi.hasFocus())
                        cmi.getDoc().setValue(scope.field.value);
                });
                scope.$watch('snDisabled', function(newValue) {
                    if (angular.isDefined(newValue)) {
                        cmi.setOption('readOnly', newValue);
                    }
                });
            }
        }
    });
    /*! RESOURCE: /scripts/app.$sp/directive.spHtmlContent.js */
    angular.module('sn.$sp').directive('spHtmlContent', function($sce) {
        return {
            template: '<p ng-bind-html="trustAsHtml(model)"></p>',
            restrict: 'E',
            replace: true,
            scope: {
                model: '='
            },
            link: function(scope, element, attrs, controller) {
                scope.trustAsHtml = $sce.trustAsHtml;
                scope.$watch('model', function() {
                    Prism.highlightAll();
                })
            }
        }
    });
    /*! RESOURCE: /scripts/app.$sp/directive.spCodeMirror.js */
    angular.module('sn.$sp').directive('spCodeMirror', function() {
        return {
            template: '<textarea class="CodeMirror" name="{{::field.name}}" ng-model="v" style="width: 100%;" data-length="{{ ::dataLength }}" data-charlimit="false">' +
                '</textarea>',
            restrict: 'E',
            replace: true,
            require: '^ngModel',
            scope: {
                field: '=',
                mode: '@',
                dataLength: '@',
                snDisabled: '=?',
                snChange: '&',
                snBlur: '&'
            },
            link: function(scope, element, attrs, ctrl) {
                element[0].value = scope.field.value;
                element[0].id = scope.field.name + "_html_editor";
                var cmi = CodeMirror.fromTextArea(element[0], {
                    mode: scope.mode,
                    lineWrapping: false,
                    readOnly: scope.snDisabled === true,
                    viewportMargin: Infinity,
                    tabSize: 2
                });
                ctrl.$viewChangeListeners.push(function() {
                    scope.$eval(attrs.ngChange);
                });
                cmi.on('change', function(cm) {
                    if ("stagedValue" in scope.field) {
                        scope.field.stagedValue = cm.getValue();
                        ctrl.$setViewValue(scope.field.stagedValue);
                    } else {
                        scope.field.value = cm.getValue();
                        ctrl.$setViewValue(scope.field.value);
                    }
                    if (angular.isDefined(scope.snChange))
                        scope.snChange();
                });
                cmi.on('blur', function(cm) {
                    if ("stagedValue" in scope.field) {
                        scope.field.stagedValue = cm.getValue();
                        ctrl.$setViewValue(scope.field.stagedValue);
                    } else {
                        scope.field.value = cm.getValue();
                        ctrl.$setViewValue(scope.field.value);
                    }
                    if (angular.isDefined(scope.snBlur))
                        scope.snBlur();
                });
                scope.$watch(function() {
                    return scope.field.value;
                }, function(newValue, oldValue) {
                    if (newValue != oldValue && !cmi.hasFocus())
                        cmi.getDoc().setValue(scope.field.value);
                });
                scope.$watch('snDisabled', function(newValue) {
                    if (angular.isDefined(newValue)) {
                        cmi.setOption('readOnly', newValue);
                    }
                });
            }
        }
    });
    /*! RESOURCE: /scripts/app.$sp/directive.spScriptEditor.js */
    angular.module('sn.$sp').directive('spScriptEditor', function($rootScope, $timeout, $http, spCodeEditorAutocomplete, defaultJSAutocomplete) {
        return {
            template: '<textarea class="CodeMirror" name="{{::field.name}}" ng-model="v" style="width: 100%;" data-length="{{::dataLength}}" data-charlimit="false">' +
                '</textarea>',
            restrict: 'E',
            require: '^ngModel',
            replace: true,
            scope: {
                field: '=',
                dataLength: '@',
                options: '@?',
                snDisabled: '=?',
                snChange: '&',
                snBlur: '&'
            },
            link: function(scope, element, attrs, ctrl) {
                element[0].value = scope.field.value;
                element[0].id = scope.field.name + "_javascript_editor";
                var cmi = initializeCodeMirror(element[0]);
                var server;
                spCodeEditorAutocomplete.getConfig('sp_widget', scope.field.name)
                    .then(setupTernServer);
                scope.$watch(function() {
                    return scope.field.value;
                }, function(newValue, oldValue) {
                    if (newValue != oldValue && !cmi.hasFocus())
                        cmi.getDoc().setValue(scope.field.value);
                });
                ctrl.$viewChangeListeners.push(function() {
                    scope.$eval(attrs.ngChange);
                });
                cmi.on('change', function(cm) {
                    if ("stagedValue" in scope.field) {
                        scope.field.stagedValue = cm.getValue();
                        ctrl.$setViewValue(scope.field.stagedValue);
                    } else {
                        scope.field.value = cm.getValue();
                        ctrl.$setViewValue(scope.field.value);
                    }
                    if (angular.isDefined(scope.snChange))
                        scope.snChange();
                });
                cmi.on('blur', function(cm) {
                    if ("stagedValue" in scope.field) {
                        scope.field.stagedValue = cm.getValue();
                        ctrl.$setViewValue(scope.field.stagedValue);
                    } else {
                        scope.field.value = cm.getValue();
                        ctrl.$setViewValue(scope.field.value);
                    }
                    if (angular.isDefined(scope.snBlur))
                        scope.snBlur();
                });
                scope.$watch('snDisabled', function(newValue) {
                    if (angular.isDefined(newValue)) {
                        cmi.setOption('readOnly', newValue);
                    }
                });
                cmi.on("keyup", function(cm, event) {
                    var keyCode = ('which' in event) ? event.which : event.keyCode;
                    var ternTooltip = document.getElementsByClassName('CodeMirror-Tern-tooltip')[0];
                    if (keyCode == 190)
                        if (event.shiftKey)
                            return;
                        else
                            server.complete(cmi, server);
                    if (keyCode == 57 && window.event.shiftKey && ternTooltip)
                        angular.element(ternTooltip).show();
                    if (keyCode == 27 && ternTooltip) {
                        angular.element(ternTooltip).hide();
                    }
                });
                cmi.on("startCompletion", function(cm) {
                    var completion = cm.state.completionActive;
                    completion.options.completeSingle = false;
                    var pick = completion.pick;
                    completion.pick = function(data, i) {
                        var completion = data.list[i];
                        CodeMirror.signal(cm, "codemirror_hint_pick", {
                            data: completion,
                            editor: cm
                        });
                        pick.apply(this, arguments);
                    }
                });
                cmi.on("codemirror_hint_pick", function(i) {
                    var data = i.data.data;
                    var editor = i.editor;
                    var cur = editor.getCursor();
                    var token = data.type;
                    if (token && token.indexOf('fn(') != -1) {
                        if (editor.getTokenAt({
                                ch: cur.ch + 1,
                                line: cur.line
                            }).string != '(') {
                            editor.replaceRange('()', {
                                line: cur.line,
                                ch: cur.ch
                            }, {
                                line: cur.line,
                                ch: cur.ch
                            });
                            if (token && token.substr(0, 4) !== 'fn()' && angular.element('div.CodeMirror-Tern-tooltip')[0]) {
                                editor.execCommand('goCharLeft');
                                setTimeout(function() {
                                    var ternTooltip = document.getElementsByClassName('CodeMirror-Tern-tooltip')[0];
                                    if (ternTooltip) {
                                        angular.element(ternTooltip).show();
                                    }
                                }, 100)
                            }
                        } else if (token && token.substr(0, 4) !== 'fn()')
                            editor.execCommand('goCharRight');
                    }
                });
    
                function initializeCodeMirror(elem) {
                    var options = {
                        mode: "javascript",
                        lineNumbers: true,
                        lineWrapping: false,
                        readOnly: scope.snDisabled === true,
                        viewportMargin: Infinity,
                        gutters: ["CodeMirror-lint-markers"],
                        lint: {
                            asi: true
                        },
                        indentWithTabs: true,
                        tabSize: 2,
                        matchBrackets: true,
                        autoCloseBrackets: true,
                        theme: "snc"
                    };
                    if (scope.options) {
                        Object.keys(scope.options).forEach(function(key) {
                            options[key] = scope.options[key];
                        });
                    }
                    return CodeMirror.fromTextArea(elem, options);
                }
    
                function setupTernServer(data) {
                    var plugins = {};
                    if (scope.field.name === "client_script")
                        plugins = {
                            "angular": "./"
                        };
                    server = new CodeMirror.TernServer({
                        defs: [data, defaultJSAutocomplete],
                        plugins: plugins
                    });
                    cmi.setOption("extraKeys", {
                        "Ctrl-Space": function(cm) {
                            server.complete(cm);
                        },
                        "Ctrl-I": function(cm) {
                            server.showType(cm);
                        },
                        "Ctrl-O": function(cm) {
                            server.showDocs(cm);
                        },
                        "Alt-.": function(cm) {
                            server.jumpToDef(cm);
                        },
                        "Alt-,": function(cm) {
                            server.jumpBack(cm);
                        },
                        "Ctrl-Q": function(cm) {
                            server.rename(cm);
                        },
                        "Ctrl-.": function(cm) {
                            server.selectName(cm);
                        }
                    });
                    cmi.on("cursorActivity", function(cm) {
                        server.updateArgHints(cm);
                    });
                }
            }
        }
    });
    /*! RESOURCE: /scripts/app.$sp/directive.spEditableField.js */
    angular.module('sn.$sp').directive('spEditableField', function(getTemplateUrl, glideFormFactory, $http, spUtil) {
        return {
            restrict: 'E',
            templateUrl: 'sp_editable_field.xml',
            scope: {
                fieldModel: "=",
                table: "@",
                tableId: "=",
                block: "=?",
                editableByUser: "=",
                onChange: "=?",
                onSubmit: "=?",
                asyncSubmitValidation: "=?"
            },
            transclude: true,
            replace: true,
            controller: function($scope) {
                var REST_API_PATH = "/api/now/v1/ui/table_edit/";
                var g_form;
                this.createShadowModel = function() {
                    $scope.shadowModel = angular.copy($scope.fieldModel);
                    $scope.shadowModel.table = $scope.table;
                    $scope.shadowModel.sys_id = $scope.tableId;
                    $scope.blockDisplay = $scope.block ? {
                        display: 'block'
                    } : {};
                    $scope.editable = !$scope.shadowModel.readonly && $scope.editableByUser;
                    $scope.fieldID = $scope.table + "-" + $scope.shadowModel.name.replace('.', '_dot_') + "-" + $scope.tableId;
                    initGlideForm();
                };
                this.createShadowModel();
                $scope.getGlideForm = function() {
                    return g_form;
                };
                $scope.saveForm = function() {
                    if (g_form)
                        g_form.submit();
                    if (angular.isDefined($scope.asyncSubmitValidation)) {
                        $scope.asyncSubmitValidation(g_form, $scope.shadowModel).then(function(result) {
                            if (result)
                                completeSave();
                        });
                    }
                };
    
                function completeSave() {
                    var url = REST_API_PATH + $scope.table + "?sysparm_records=" + $scope.tableId + "&sysparm_view=default&sysparm_fields=" + $scope.shadowModel.name;
                    var data = {};
                    data[$scope.shadowModel.name] = $scope.shadowModel.value;
                    $http.put(url, data).success(function(data) {
                        if (data.result && Array.isArray(data.result.records))
                            updateFieldModel(data.result.records);
                        $scope.closePopover();
                    });
                }
    
                function updateFieldModel(records) {
                    for (var i = 0; i < records.length; i++) {
                        var r = records[i];
                        if (r.data && $scope.fieldModel.name in r.data) {
                            var updated = r.data[$scope.fieldModel.name];
                            $scope.fieldModel.value = updated.value;
                            $scope.fieldModel.displayValue = updated.display_value;
                        }
                    }
                }
    
                function initGlideForm() {
                    if (g_form)
                        g_form.$private.events.cleanup();
                    var uiMessageHandler = function(g_form, type, message) {
                        switch (type) {
                            case 'infoMessage':
                                spUtil.addInfoMessage(message);
                                break;
                            case 'errorMessage':
                                spUtil.addErrorMessage(message);
                                break;
                            case 'clearMessages':
                                break;
                            default:
                                return false;
                        }
                    };
                    g_form = glideFormFactory.create($scope, $scope.table, $scope.tableId, [$scope.shadowModel], null, {
                        uiMessageHandler: uiMessageHandler
                    });
                    $scope.$emit("spEditableField.gForm.initialized", g_form, $scope.shadowModel);
                    if (angular.isDefined($scope.onChange))
                        g_form.$private.events.on("change", function(fieldName, oldValue, newValue) {
                            return $scope.onChange.call($scope.onChange, g_form, $scope.shadowModel, oldValue, newValue);
                        });
                    if (angular.isDefined($scope.onSubmit))
                        g_form.$private.events.on("submit", function() {
                            return $scope.onSubmit.call($scope.onSubmit, g_form, $scope.shadowModel);
                        });
                    if (!angular.isDefined($scope.asyncSubmitValidation)) {
                        g_form.$private.events.on('submitted', function() {
                            completeSave();
                        });
                    }
                }
            },
            link: function(scope, el, attrs, ctrl) {
                scope.closePopover = function() {
                    if (scope.shadowModel.popoverIsOpen)
                        ctrl.createShadowModel();
                    scope.shadowModel.popoverIsOpen = false;
                }
                $('body').on('click', function(event) {
                    var $et = $(event.target);
                    if (!($et.closest(".popover-" + scope.fieldID).length ||
                            $et.closest(".popover-trigger-" + scope.fieldID).length)) {
                        scope.$evalAsync('closePopover()');
                    }
                })
                scope.$on('sp.spFormField.rendered', function(e, element, input) {
                    input.focus();
                })
            }
        }
    });
    angular.module('sn.$sp').directive('spEditableField2', function(getTemplateUrl, glideFormFactory, $http, spUtil, glideFormFieldFactory) {
        return {
            restrict: 'E',
            templateUrl: 'sp_editable_field.xml',
            scope: {
                fieldModel: "=",
                table: "@",
                tableId: "=",
                block: "=?",
                editableByUser: "=",
                onChange: "=?",
                onSubmit: "=?",
                label: "@?"
            },
            transclude: true,
            replace: true,
            controller: function($scope) {
                $scope.v2 = true;
                var REST_API_PATH = "/api/now/v1/ui/table_edit/";
                var g_form;
                $scope.fieldModel = $scope.fieldModel || {};
                if (angular.isDefined($scope.label))
                    $scope.fieldModel.label = $scope.label;
                $scope.editable = !$scope.fieldModel.readonly && $scope.editableByUser;
                $scope.fieldID = $scope.table + "-" + $scope.fieldModel.name + "-" + $scope.tableId;
                initGlideForm();
                $scope.getGlideForm = function() {
                    return g_form;
                };
                $scope.$on('sp.spEditableField.save', function(e, fieldModel) {
                    if (fieldModel == $scope.fieldModel)
                        $scope.saveForm();
                });
                $scope.saveForm = function() {
                    if (g_form)
                        g_form.submit();
                };
    
                function completeSave() {
                    var url = REST_API_PATH + $scope.table + "?sysparm_records=" + $scope.tableId + "&sysparm_view=default&sysparm_fields=" + $scope.fieldModel.name;
                    var data = {};
                    data[$scope.fieldModel.name] = $scope.fieldModel.value;
                    $http.put(url, data)
                        .success(function(data) {
                            console.log("Field update successful", data);
                        })
                        .error(function(reason) {
                            console.log("Field update failure", reason);
                        });
                }
    
                function initGlideForm() {
                    if (g_form)
                        g_form.$private.events.cleanup();
                    var uiMessageHandler = function(g_form, type, message) {
                        switch (type) {
                            case 'addInfoMessage':
                                spUtil.addInfoMessage(message);
                                break;
                            case 'addErrorMessage':
                                spUtil.addErrorMessage(message);
                                break;
                            case 'clearMessages':
                                break;
                            default:
                        }
                    };
                    g_form = glideFormFactory.create($scope, $scope.table, $scope.tableId, [$scope.fieldModel], null, {
                        uiMessageHandler: uiMessageHandler
                    });
                    $scope.$emit("spEditableField.gForm.initialized", g_form, $scope.fieldModel);
                    if (angular.isDefined($scope.onChange)) {
                        g_form.$private.events.on("change", function(fieldName, oldValue, newValue) {
                            return $scope.onChange.call($scope.onChange, g_form, $scope.fieldModel, oldValue, newValue);
                        });
                    }
                    if (angular.isDefined($scope.onSubmit))
                        g_form.$private.events.on("submit", function() {
                            return $scope.onSubmit.call($scope.onSubmit, g_form);
                        });
                    g_form.$private.events.on('submitted', function() {
                        completeSave();
                    });
                }
            }
        }
    });;
    /*! RESOURCE: /scripts/app.$sp/directive.spFieldListElement.js */
    angular.module('sn.$sp').directive('snFieldListElement', function(getTemplateUrl, $http, urlTools, $timeout, $sanitize, i18n, $filter, nowServer) {
        "use strict";
        return {
            restrict: 'E',
            replace: true,
            scope: {
                field: '=',
                snChange: '&',
                getGlideForm: '&glideForm',
                snDisabled: '='
            },
            template: '<input type="text" ng-disabled="snDisabled" style="min-width: 150px;" name="{{field.name}}" ng-model="field.value" />',
            controller: function($scope) {
                $scope.table = $scope.field.ed.dependent_value;
                $scope.$watch('field.dependentValue', function(newVal, oldVal) {
                    if (!angular.isDefined(newVal))
                        return;
                    if (newVal != oldVal)
                        console.log("Should have changed tables to " + newVal);
                    $scope.table = $scope.field.dependentValue;
                    var src = nowServer.getURL('table_fields', 'exclude_formatters=true&fd_table=' + newVal);
                    $http.post(src).success(function(response) {
                        $scope.field.choices = response;
                    });
                });
            },
            link: function(scope, element) {
                var orderBy = $filter('orderBy');
                var isExecuting = false;
                var fieldCache = {};
                var data = [];
                var term = "";
                var initTimeout = null;
                var value = scope.field.value;
                var oldValue = scope.field.value;
                var $select;
                var previousScrollTop;
                var select2Helpers = {
                    query: function(q) {
                        term = q.term;
                        if (data.length == 0) {
                            getFieldsForTable(scope.table, function(tableName, fields) {
                                data = fields;
                                filterData(q);
                            });
                        } else
                            filterData(q);
                    },
                    initSelection: function(elem, callback) {
                        if (scope.field.displayValue) {
                            var items = [];
                            var values = scope.field.value.split(',');
                            var displayValues = scope.field.displayValue.split(',');
                            for (var i = 0; i < values.length; i++)
                                items.push({
                                    id: values[i],
                                    text: displayValues[i]
                                });
                            callback(items);
                        } else
                            callback([]);
                    },
                    formatResult: function(object, container, query) {
                        var row = object.text;
                        if (object.reference && !object.children)
                            row += "<span style='float: right' class='expand fa fa-chevron-right' data-id='" + object.id + "' data-reference='" + object.reference + "'></span>";
                        return row;
                    }
                };
                var config = {
                    containerCssClass: 'select2-reference ng-form-element',
                    placeholder: '    ',
                    formatSearching: '',
                    allowClear: true,
                    query: select2Helpers.query,
                    initSelection: select2Helpers.initSelection,
                    formatResult: select2Helpers.formatResult,
                    closeOnSelect: false,
                    multiple: true
                };
    
                function filterData(q) {
                    var r = {
                        results: []
                    };
                    for (var c in data) {
                        var row = data[c];
                        if (q.term.length == 0 || row.text.toUpperCase().indexOf(q.term.toUpperCase()) >= 0 || row.id.toUpperCase().indexOf(q.term.toUpperCase()) >= 0)
                            r.results.push(row);
                    }
                    q.callback(r);
                }
    
                function init() {
                    $timeout.cancel(initTimeout);
                    initTimeout = $timeout(function() {
                        i18n.getMessage('Searching...', function(searchingMsg) {
                            config.formatSearching = function() {
                                return searchingMsg;
                            };
                        });
                        element.css("opacity", 1);
                        element.select2("destroy");
                        $select = element.select2(config);
                        $select.bind("select2-open", onDropdownShow);
                        $select.bind("select2-close", onDropdownClose);
                        $select.bind("select2-selecting", onSelecting);
                        $select.bind("select2-removing", onRemoving);
                        $select.bind("change", onChange);
                        $select.bind("select2-loaded", onResultsLoaded);
                        var sortable = new Sortable($select.select2("container").find("ul.select2-choices").get(0), {
                            onStart: function() {
                                $select.select2("onSortStart");
                            },
                            onEnd: function() {
                                $select.select2("onSortEnd");
                            }
                        });
                    });
                }
    
                function expandHandler(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    if (e.type == 'click') {
                        var $el = angular.element(this);
                        previousScrollTop = $el.parents('ul.select2-results').scrollTop();
                        var d = $el.data();
                        var targetRow = getDataRowByFieldName(d.id);
                        getFieldsForTable(d.reference, function(tableName, refFields) {
                            for (var i = 0; i < refFields.length; i++)
                                refFields[i].id = d.id + '.' + refFields[i].id;
                            targetRow.children = refFields;
                            $select.select2("search", term);
                        });
                    }
                };
    
                function getDataRowByFieldName(fieldName) {
                    var fieldNames = fieldName.split('.');
                    var row = getDataRowByFieldNamePart(fieldNames[0], data);
                    if (fieldNames.length > 1)
                        for (var i = 1; i < fieldNames.length; i++)
                            row = getDataRowByFieldNamePart(fieldNames[i], row.children);
                    return row;
                }
    
                function getDataRowByFieldNamePart(fieldNamePart, fieldArr) {
                    for (var i = 0; i < fieldArr.length; i++)
                        if (fieldArr[i].fieldName == fieldNamePart) return fieldArr[i];
                }
    
                function getFieldsForTable(tableName, callback) {
                    if (tableName in fieldCache) {
                        var fields = getOrderedFieldsFromCache(tableName);
                        callback.call(this, tableName, fields);
                        return;
                    }
                    $http.get('/api/now/ui/meta/' + tableName).then(function(r) {
                        var fields = [];
                        if (r.data && r.data.result && r.data.result.columns) {
                            fieldCache[tableName] = r.data.result.columns;
                            fields = getOrderedFieldsFromCache(tableName);
                        }
                        callback.call(this, tableName, fields);
                    });
    
                    function getOrderedFieldsFromCache(tableName) {
                        var col, cols = [],
                            fields = fieldCache[tableName];
                        for (var c in fields) {
                            col = fields[c];
                            cols.push({
                                fieldName: col.name,
                                id: col.name,
                                text: col.label,
                                reference: col.reference
                            });
                        }
                        return orderBy(cols, 'text', false);
                    }
                }
    
                function onResultsLoaded() {
                    if (!previousScrollTop)
                        return;
                    $timeout(function() {
                        angular.element('ul.select2-results').scrollTop(previousScrollTop);
                        previousScrollTop = null;
                    });
                }
    
                function onDropdownShow() {
                    angular.element('ul.select2-results').on('mousedown click mouseup', 'span.expand', expandHandler);
                }
    
                function onDropdownClose() {
                    angular.element('ul.select2-results').off('mousedown click mouseup', 'span.expand', expandHandler);
                }
    
                function onChange(e) {
                    setValue(e.val, e);
                }
    
                function onSelecting(e) {
                    var selectedItem = e.choice;
                    if (selectedItem['id'] != '') {
                        var values = scope.field.value == '' ? [] : scope.field.value.split(',');
                        values.push(selectedItem['id']);
                        setValue(values, e);
                    }
                }
    
                function onRemoving(e) {
                    var removed = e.choice;
                    var values = scope.field.value.split(',');
                    for (var i = values.length - 1; i >= 0; i--) {
                        if (removed['id'] == values[i]) {
                            values.splice(i, 1);
                            break;
                        }
                    }
                    setValue(values, e);
                }
    
                function setValue(values, e) {
                    isExecuting = true;
                    oldValue = scope.field.value;
                    scope.field.value = scope.field.displayValue = values.join(',');
                    e.preventDefault();
                    $select.select2('val', scope.field.value.split(','));
                    scope.$apply(function() {
                        if (scope.snChange)
                            scope.snChange({
                                field: scope.field,
                                newValue: scope.field.value,
                                displayValue: scope.field.displayValue,
                                oldValue: oldValue
                            });
                        isExecuting = false;
                    });
                }
                scope.$watch("field.value", function(newValue) {
                    if (isExecuting) return;
                    if (angular.isDefined(newValue) && $select) {
                        $select.select2('val', newValue.split(',')).select2('close');
                    }
                });
                init();
            }
        };
    });;
    /*! RESOURCE: /scripts/app.$sp/directive.spReferenceElement.js */
    angular.module('sn.$sp').directive('spReferenceElement', function($timeout, $http, urlTools, filterExpressionParser, $sanitize, i18n, spIs) {
        "use strict";
        return {
            restrict: 'E',
            replace: true,
            scope: {
                ed: "=?",
                field: "=",
                refTable: "=?",
                refId: "=?",
                snOptions: "=?",
                snOnBlur: "&",
                snOnClose: "&",
                minimumInputLength: "@",
                snDisabled: "=",
                dropdownCssClass: "@",
                formatResultCssClass: "&",
                displayColumn: "@",
                recordValues: '&',
                getGlideForm: '&glideForm',
                domain: "@",
                snSelectWidth: '@',
            },
            template: '<input type="text" name="{{field.name}}" ng-disabled="snDisabled" style="min-width: 150px;" />',
            link: function(scope, element, attrs, ctrl) {
                scope.ed = scope.ed || scope.field.ed;
                scope.selectWidth = scope.snSelectWidth || '100%';
                element.css("opacity", 0);
                var fireReadyEvent = true;
                var g_form;
                var displayColumns;
                var refAutoCompleter;
                var refOrderBy;
                var field = scope.field;
                var isMultiple = scope.snOptions && scope.snOptions.multiple === true;
                if (angular.isDefined(scope.getGlideForm))
                    g_form = scope.getGlideForm();
                var fieldAttributes = {};
                if (angular.isDefined(scope.field) && angular.isDefined(scope.field.attributes) && typeof scope.ed.attributes == 'undefined')
                    if (Array.isArray(scope.field.attributes))
                        fieldAttributes = scope.field.attributes;
                    else
                        fieldAttributes = parseAttributes(scope.field.attributes);
                else
                    fieldAttributes = parseAttributes(scope.ed.attributes);
                if (angular.isDefined(fieldAttributes['ref_ac_columns']))
                    displayColumns = fieldAttributes['ref_ac_columns'];
                if (angular.isDefined(fieldAttributes['ref_auto_completer']))
                    refAutoCompleter = fieldAttributes['ref_auto_completer'];
                else
                    refAutoCompleter = "AJAXReferenceCompleter";
                if (angular.isDefined(fieldAttributes['ref_ac_order_by']))
                    refOrderBy = fieldAttributes['ref_ac_order_by'];
                var s2Helpers = {
                    formatSelection: function(item) {
                        return $sanitize(getDisplayValue(item));
                    },
                    formatResult: function(item) {
                        var displayValues = getDisplayValues(item);
                        if (displayValues.length == 1)
                            return $sanitize(displayValues[0]);
                        if (displayValues.length > 1) {
                            var width = 100 / displayValues.length;
                            var markup = "";
                            for (var i = 0; i < displayValues.length; i++)
                                markup += "<div style='width: " + width + "%;' class='select2-result-cell'>" + $sanitize(displayValues[i]) + "</div>";
                            return markup;
                        }
                        return "";
                    },
                    search: function(queryParams) {
                        var url = urlTools.getURL('sp_ref_list_data');
                        return $http.post(url, queryParams.data).then(function(response) {
                            queryParams.success(response);
                        });
                    },
                    initSelection: function(elem, callback) {
                        if (scope.field.displayValue) {
                            if (isMultiple) {
                                var items = [];
                                var values = scope.field.value.split(',');
                                var displayValues = scope.field.display_value_list;
                                if (Array.isArray(scope.field.displayValue)) {
                                    displayValues.length = 0;
                                    for (var i in scope.field.displayValue)
                                        displayValues[i] = scope.field.displayValue[i];
                                    scope.field.displayValue = displayValues.join(g_glide_list_separator);
                                } else if (values.length == 1) {
                                    displayValues.length = 0;
                                    displayValues[0] = scope.field.displayValue;
                                } else if (scope.field.displayValue != displayValues.join(g_glide_list_separator)) {
                                    displayValues.length = 0;
                                    var split = scope.field.displayValue.split(',');
                                    for (var i in split)
                                        displayValues[i] = split[i];
                                }
                                for (var i = 0; i < values.length; i++) {
                                    items.push({
                                        sys_id: values[i],
                                        name: displayValues[i]
                                    });
                                }
                                callback(items);
                            } else {
                                callback({
                                    sys_id: scope.field.value,
                                    name: scope.field.displayValue
                                });
                            }
                        } else
                            callback([]);
                    },
                    onSelecting: function(e) {
                        var selectedItem = e.choice;
                        if ('sys_id' in selectedItem) {
                            var values = field.value == '' ? [] : field.value.split(',');
                            var displayValues = field.display_value_list;
                            values.push(selectedItem.sys_id);
                            displayValues.push(getDisplayValue(selectedItem));
                            g_form.setValue(field.name, values.join(','), displayValues.join(g_glide_list_separator));
                            e.preventDefault();
                            element.select2('val', values).select2('close');
                        }
                    },
                    onRemoving: function(e) {
                        var removed = e.choice;
                        var values = field.value.split(',');
                        var displayValues = field.display_value_list;
                        for (var i = values.length - 1; i >= 0; i--) {
                            if (removed.sys_id == values[i]) {
                                values.splice(i, 1);
                                displayValues.splice(i, 1);
                                break;
                            }
                        }
                        g_form.setValue(field.name, values.join(','), displayValues.join(g_glide_list_separator));
                        e.preventDefault();
                        element.select2('val', values);
                    },
                    select2Change: function(e) {
                        e.stopImmediatePropagation();
                        if (e.added) {
                            var selectedItem = e.added;
                            var value = selectedItem.sys_id;
                            var displayValue = value ? getDisplayValue(selectedItem) : '';
                            if (scope.field['_cat_variable'] === true && ('price' in selectedItem || 'recurring_price' in selectedItem))
                                setPrice(selectedItem.price, selectedItem.recurring_price);
                            g_form.setValue(scope.field.name, value, displayValue);
                        } else if (e.removed) {
                            if (scope.field['_cat_variable'] === true)
                                setPrice(0, 0);
                            g_form.clearValue(scope.field.name);
                        }
                    }
                };
                var config = {
                    width: scope.selectWidth,
                    minimumInputLength: scope.minimumInputLength ? parseInt(scope.minimumInputLength, 10) : 0,
                    containerCssClass: 'select2-reference ng-form-element',
                    placeholder: '   ',
                    formatSearching: '',
                    allowClear: attrs.allowClear !== 'false',
                    id: function(item) {
                        return item.sys_id;
                    },
                    sortResults: (scope.snOptions && scope.snOptions.sortResults) ? scope.snOptions.sortResults : undefined,
                    ajax: {
                        quietMillis: NOW.ac_wait_time,
                        data: function(filterText, page) {
                            var filterExpression = filterExpressionParser.parse(filterText, scope.ed.defaultOperator);
                            var q = '';
                            var columnsToSearch = getReferenceColumnsToSearch();
                            var queryArr = [];
                            var query;
                            columnsToSearch.forEach(function(colToSearch) {
                                query = "";
                                if (field.ed.queryString)
                                    query += field.ed.queryString + '^';
                                query += colToSearch + filterExpression.operator + filterExpression.filterText +
                                    '^' + colToSearch + 'ISNOTEMPTY' + getExcludedValues();
                                queryArr.push(query);
                            });
                            q += queryArr.join("^NQ");
                            if (refOrderBy)
                                q += "^ORDERBY" + refOrderBy;
                            q += "^EQ";
                            var params = {
                                start: (scope.pageSize * (page - 1)),
                                count: scope.pageSize,
                                sysparm_target_table: scope.refTable,
                                sysparm_target_sys_id: scope.refId,
                                sysparm_target_field: scope.ed.name,
                                table: scope.ed.reference,
                                qualifier: scope.ed.qualifier,
                                data_adapter: scope.ed.data_adapter,
                                attributes: scope.ed.attributes,
                                dependent_field: scope.ed.dependent_field,
                                dependent_table: scope.ed.dependent_table,
                                dependent_value: scope.ed.dependent_value,
                                p: scope.ed.reference + ';q:' + q + ';r:' + scope.ed.qualifier
                            };
                            if (displayColumns)
                                params.required_fields = displayColumns.split(";").join(":");
                            if (scope.domain) {
                                params.sysparm_domain = scope.domain;
                            }
                            if (angular.isDefined(scope.field) && scope.field['_cat_variable'] === true) {
                                delete params['sysparm_target_table'];
                                params['sysparm_include_variables'] = true;
                                params['variable_ids'] = scope.field.sys_id;
                                var getFieldSequence = g_form.$private.options('getFieldSequence');
                                if (getFieldSequence) {
                                    params['variable_sequence1'] = getFieldSequence();
                                }
                                var itemSysId = g_form.$private.options('itemSysId');
                                params['sysparm_id'] = itemSysId;
                                var getFieldParams = g_form.$private.options('getFieldParams');
                                if (getFieldParams) {
                                    angular.extend(params, getFieldParams());
                                }
                            }
                            if (scope.recordValues)
                                params.sysparm_record_values = scope.recordValues();
                            return params;
                        },
                        results: function(data, page) {
                            return ctrl.filterResults(data, page, scope.pageSize);
                        },
                        transport: s2Helpers.search
                    },
                    formatSelection: s2Helpers.formatSelection,
                    formatResult: s2Helpers.formatResult,
                    initSelection: s2Helpers.initSelection,
                    dropdownCssClass: attrs.dropdownCssClass,
                    formatResultCssClass: scope.formatResultCssClass || null,
                    multiple: isMultiple
                };
                if (isMultiple && scope.ed.reference == "sys_user") {
                    config.createSearchChoice = function(term) {
                        if (spIs.an.email(term)) {
                            return {
                                email: term,
                                name: term,
                                user_name: term,
                                sys_id: term
                            };
                        }
                    };
                }
                if (scope.snOptions) {
                    if (scope.snOptions.placeholder) {
                        config.placeholder = scope.snOptions.placeholder;
                    }
                    if (scope.snOptions.width) {
                        config.width = scope.snOptions.width;
                    }
                }
    
                function getReferenceColumnsToSearch() {
                    var colNames = ['name'];
                    if (fieldAttributes['ref_ac_columns_search'] == 'true' && 'ref_ac_columns' in fieldAttributes && fieldAttributes['ref_ac_columns'] != '') {
                        colNames = fieldAttributes['ref_ac_columns'].split(';');
                        if (scope.ed.searchField)
                            colNames.push(scope.ed.searchField);
                    } else if (scope.ed.searchField)
                        colNames = [scope.ed.searchField];
                    else if (fieldAttributes['ref_ac_order_by'])
                        colNames = [fieldAttributes['ref_ac_order_by']];
                    return colNames.filter(onlyUnique);
                }
    
                function getExcludedValues() {
                    if (scope.ed.excludeValues && scope.ed.excludeValues != '') {
                        return '^sys_idNOT IN' + scope.ed.excludeValues;
                    }
                    return '';
                }
    
                function parseAttributes(strAttributes) {
                    if (typeof strAttributes === 'object')
                        return strAttributes;
                    var attributeArray = (strAttributes && strAttributes.length ? strAttributes.split(',') : []);
                    var attributeObj = {};
                    for (var i = 0; i < attributeArray.length; i++) {
                        if (attributeArray[i].length > 0) {
                            var attribute = attributeArray[i].split('=');
                            attributeObj[attribute[0]] = attribute.length > 1 ? attribute[1] : '';
                        }
                    }
                    return attributeObj;
                }
    
                function init() {
                    $timeout(function() {
                        i18n.getMessage('Searching...', function(searchingMsg) {
                            config.formatSearching = function() {
                                return searchingMsg;
                            };
                        });
                        element.css("opacity", 1);
                        element.select2("destroy");
                        var select2 = element.select2(config);
                        element.select2("val", scope.field.value.split(','));
                        if (isMultiple) {
                            element.bind("select2-selecting", s2Helpers.onSelecting);
                            element.bind("select2-removing", s2Helpers.onRemoving);
                        } else {
                            element.bind("change select2-removed", s2Helpers.select2Change);
                        }
                        element.bind("select2-blur", function() {
                            $timeout(function() {
                                scope.snOnBlur();
                            });
                        });
                        if (fireReadyEvent) {
                            scope.$emit('select2.ready', element);
                            fireReadyEvent = false;
                        }
                    });
                }
    
                function getDisplayValue(selectedItem) {
                    var displayValue = '';
                    if (selectedItem && selectedItem.sys_id) {
                        if (scope.displayColumn && typeof selectedItem[scope.displayColumn] != "undefined")
                            displayValue = selectedItem[scope.displayColumn];
                        else if (selectedItem.$$displayValue)
                            displayValue = selectedItem.$$displayValue;
                        else if (selectedItem.name)
                            displayValue = selectedItem.name;
                        else if (selectedItem.title)
                            displayValue = selectedItem.title;
                    }
                    return displayValue;
                }
    
                function getDisplayValues(selectedItem) {
                    var displayValues = [];
                    if (selectedItem && selectedItem.sys_id) {
                        displayValues.push(getDisplayValue(selectedItem));
                    }
                    if (displayColumns && refAutoCompleter === "AJAXTableCompleter") {
                        var columns = displayColumns.split(";");
                        for (var i = 0; i < columns.length; i++) {
                            var column = columns[i];
                            if (selectedItem[column])
                                displayValues.push(selectedItem[column]);
                        }
                    }
                    return displayValues.filter(onlyUnique);
                }
    
                function onlyUnique(value, index, self) {
                    return self.indexOf(value) === index;
                }
    
                function setPrice(p, rp) {
                    scope.field.price = p;
                    scope.field.recurring_price = rp;
                }
                g_form.$private.events.on("change", function(fieldName, oldValue, value) {
                    if (fieldName == field.name) {
                        if (value == "" && scope.field.display_value_list)
                            scope.field.display_value_list.length = 0;
                        element.select2("val", typeof value == 'string' ? value.split(',') : value);
                    }
                });
                scope.$on("snReferencePicker.activate", function(evt, parms) {
                    $timeout(function() {
                        element.select2("open");
                    })
                });
                init();
            },
            controller: function($scope, $rootScope) {
                $scope.pageSize = 20;
                this.filterResults = function(data, page) {
                    return {
                        results: data.data.items,
                        more: (page * $scope.pageSize < data.data.total)
                    };
                };
            }
        };
    });;
    /*! RESOURCE: /scripts/app.$sp/directive.spCurrencyElement.js */
    angular.module('sn.$sp').directive('spCurrencyElement', function() {
        return {
            templateUrl: 'sp_element_currency.xml',
            restrict: 'E',
            replace: true,
            scope: {
                field: '=',
                snBlur: '&',
                snChange: '&',
                'getGlideForm': '&glideForm'
            },
            controller: function($scope) {
                var g_form = $scope.getGlideForm();
                var field = $scope.field;
                g_form.$private.events.on("change", function(fieldName, oldValue, newValue) {
                    if (fieldName == field.name) {
                        if (newValue.indexOf(";") > 0) {
                            var v = newValue.split(";");
                            field.currencyCode = v[0];
                            field.currencyValue = v[1];
                        } else
                            field.currencyValue = newValue;
                    }
                });
                $scope.formatValue = function(shouldSetValue) {
                    var v = field.currencyValue;
                    if (field.currencyValue != "")
                        v = field.currencyCode + ";" + field.currencyValue;
                    field.stagedValue = v;
                    $scope.snChange();
                    if (shouldSetValue)
                        $scope.snBlur();
                }
            }
        }
    });
    /*! RESOURCE: /scripts/app.$sp/directive.spDurationElement.js */
    angular.module('sn.$sp').directive('spDurationElement', function() {
        "use strict";
    
        function getVisibleUnits(attributes) {
            var maxUnit = "days";
            var o = {
                days: ["days", "hours", "minutes", "seconds"],
                hours: ["hours", "minutes", "seconds"],
                minutes: ["minutes", "seconds"],
                seconds: ["seconds"]
            };
            if (attributes && attributes.max_unit && attributes.max_unit in o)
                maxUnit = attributes.max_unit;
            return o[maxUnit];
        }
        return {
            restrict: 'E',
            replace: true,
            require: 'ngModel',
            templateUrl: 'sp_element_duration.xml',
            link: function(scope, element, attrs, ngModelCtrl) {
                var theDawnOfTime;
                scope.field = scope.$eval(attrs.field);
                scope.visibleUnits = getVisibleUnits(scope.field.attributes);
                ngModelCtrl.$formatters.push(function() {
                    if (!ngModelCtrl.$modelValue)
                        return {
                            days: 0,
                            hours: 0,
                            minutes: 0,
                            seconds: 0
                        };
                    theDawnOfTime = moment("1970-01-01 00:00:00");
                    var dur = moment.duration(moment(ngModelCtrl.$modelValue).diff(theDawnOfTime));
                    if (moment(ngModelCtrl.$modelValue).isDST())
                        dur.add(1, "hours");
                    var d = parseInt(dur.asDays(), 10);
                    var h = dur.get('hours');
                    var m = dur.get('minutes');
                    var s = dur.get('seconds');
                    if (scope.visibleUnits[0] == "hours") {
                        h = h + (d * 24);
                        d = 0;
                    } else if (scope.visibleUnits[0] == "minutes") {
                        m = m + (h * 60) + (d * 1440);
                        d = h = 0;
                    } else if (scope.visibleUnits[0] == "seconds") {
                        s = s + (m * 60) + (h * 3600) + (d * 86400);
                        d = h = m = 0;
                    }
                    return {
                        days: d,
                        hours: h,
                        minutes: m,
                        seconds: s
                    };
                });
                ngModelCtrl.$render = function() {
                    scope.parts = ngModelCtrl.$viewValue;
                };
                ngModelCtrl.$parsers.push(function(model) {
                    theDawnOfTime = moment("1970-01-01 00:00:00");
                    var modelValue = moment.duration(model);
                    var newValue = theDawnOfTime.add(modelValue).format("YYYY-MM-DD HH:mm:ss");
                    return newValue;
                });
                scope.updateDuration = function() {
                    ngModelCtrl.$setViewValue(angular.copy(scope.parts));
                };
                scope.showLabel = function(unit) {
                    if (unit == "days" || unit == "hours")
                        return true;
                    if (scope.visibleUnits[0] == "minutes")
                        return unit == "minutes";
                    return scope.visibleUnits[0] == "seconds";
                };
            }
        };
    });;
    /*! RESOURCE: /scripts/app.$sp/controller.spLogin.js */
    angular.module("sn.$sp").controller("spLogin", function($scope, $http, $window, urlTools, $location, i18n) {
        $scope.login = function(username, password) {
            var url = urlTools.getURL('view_form.login');
            var pageId = $location.search().id || $scope.page.id;
            var isLoginPage = $scope.portal.login_page_dv == pageId;
            return $http({
                method: 'post',
                url: url,
                data: urlTools.encodeURIParameters({
                    'sysparm_type': 'login',
                    'ni.nolog.user_password': true,
                    'remember_me': typeof remember_me != 'undefined' && !!remember_me ? true : false,
                    'user_name': username,
                    'user_password': password,
                    'get_redirect_url': true,
                    'sysparm_goto_url': isLoginPage ? null : $location.url()
                }),
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                }
            }).then(function(response) {
                if (!response.data) {
                    $scope.message = i18n.getMessage("There was an error processing your request");
                    return;
                }
                if (response.data.status == 'success') {
                    $scope.success = response.data.message;
                    $window.location = response.data.redirect_url;
                } else {
                    $scope.message = response.data.message;
                }
            }, function errorCallback(response) {
                $scope.message = i18n.getMessage("There was an error processing your request");
            });
        }
    });
    /*! RESOURCE: /scripts/app.$sp/directive.spMessageDialog.js */
    angular.module("sn.$sp").directive('spMessageDialog', function(nowServer, i18n, $timeout) {
        return {
            restrict: 'E',
            scope: {
                name: '@',
                title: '@',
                message: '@',
                question: '@',
                ok: '@',
                cancel: '@',
                dialogClass: '@',
                checkboxMessage: '@',
                checkboxCallback: '&',
                checkboxState: '='
            },
            replace: true,
            templateUrl: 'sp_dialog.xml',
            link: function(scope, element) {
                element.remove();
                element.appendTo($('body'));
                if (scope.checkboxMessage) {
                    scope.checkboxModel = {
                        value: scope.checkboxState
                    };
                    scope.update = function() {
                        scope.checkboxState = scope.checkboxModel.value;
                        $timeout(function() {
                            scope.checkboxCallback()(scope.checkboxState);
                        })
                    }
                }
            }
        }
    });
    /*! RESOURCE: /scripts/app.$sp/controller.spPage.js */
    angular.module("sn.$sp").controller("spPage", function($scope, $http, $location, $window, $timeout, spUtil, nowServer, snRecordWatcher, cabrillo, $rootScope, glideUserSession) {
        var _ = $window._;
        $scope.firstPage = true;
        $scope.page = {};
        $scope.page.title = "Loading...";
        $scope.theme = {};
        $scope.portal = {};
        $scope.sessions = {};
        $scope.status = "";
        $scope.isViewNative = cabrillo.isNative();
        $scope.openWindow = function(parms) {
            var jo = JSON.parse(parms);
            var left = window.screenX + window.innerWidth - 540;
            var top = window.screenY + 140;
            window.open(jo.url, jo.name, "left=" + left + ",top=" + top + "," + jo.specs);
        };
        $scope.parseJSON = function(str) {
            return JSON.parse(str);
        }
        $scope.getContainerClasses = function(container) {
            var classes = {};
            classes[container.width] = !container.bootstrap_alt;
            classes[container.container_class_name] = true;
            return classes;
        }
        var oid = $location.search().id;
        var oldPath = $location.path();
        $rootScope.$on('$locationChangeSuccess', function(e, newUrl, oldUrl) {
            $scope.$broadcast("$$uiNotification.dismiss");
            $scope.locationChanged = (oldUrl != newUrl);
            var s = $location.search();
            var p = $location.path();
            if (oldPath != p) {
                $window.location.href = $location.absUrl();
                return;
            }
            if (angular.isDefined($scope.containers) && oid == s.id && s.spa) {
                e.pageIsHandling = true;
                return;
            }
            if (p.indexOf(".do") > 0 && p.indexOf("sp.do") == -1) {
                var newUrl = $location.absUrl();
                newUrl = newUrl.substr(newUrl.search(/[^\/]+.do/));
                $window.location.href = "/" + newUrl;
                return;
            }
            if (!window.NOW.has_access && $scope.locationChanged) {
                $window.location.href = $location.absUrl();
                return;
            }
            oid = s.id;
            var t = getUrl();
            refreshPage(t);
        });
    
        function getUrl() {
            var currentParms = $location.search();
            var params = {};
            angular.extend(params, currentParms);
            params.time = new Date().getTime();
            params.portal_id = $scope.portal_id;
            params.request_uri = $location.url();
            return '/api/now/sp/page?' + $.param(params);
        }
    
        function loadPage(response) {
            $scope.firstPage = false;
            $scope.containers = _.filter(response.containers, {
                'subheader': false
            });
            $scope.subheaders = _.filter(response.containers, {
                'subheader': true
            });
            $scope.rectangles = response.rectangles;
            $scope.style = '';
            var p = response.page;
            var u = response.user;
            if (!isPublicOrUserLoggedIn(p, u)) {
                if ($scope.locationChanged) {
                    $window.location.href = $location.absUrl();
                    return;
                }
            }
            $rootScope.page = $scope.page = p;
            setCSS(p);
            if (response.portal.title)
                $window.document.title = (p.title) ? response.portal.title + ' - ' + p.title : response.portal.title;
            else
                $window.document.title = p.title;
            $timeout(function() {
                jQuery('section, .flex-item').scrollTop(0);
            });
            $rootScope.theme = $scope.theme = response.theme;
            var style = [];
            if ($scope.isNative)
                style.push('isNative');
            if ($scope.theme.navbar_fixed)
                style.push('fixed-header');
            if ($scope.theme.footer_fixed)
                style.push('fixed-footer');
            $scope.style = style.join(' ');
            response.portal.logoutUrl = "/logout.do?sysparm_goto_url=/" + response.portal.url_suffix;
            $rootScope.portal = $scope.portal = response.portal;
            if (!$scope.user) {
                $rootScope.user = $scope.user = {};
                glideUserSession.loadCurrentUser().then(function(g_user) {
                    $rootScope.g_user = g_user;
                });
            }
            angular.extend($scope.user, response.user);
            $scope.user.logged_in = $scope.user.user_name != 'guest';
            $scope.$broadcast('$$uiNotification', response.$$uiNotification);
            snRecordWatcher.init();
        }
        var pageLoaded = false;
        $scope.$on('sp.page.reload', function() {
            var t = getUrl();
            refreshPage(t);
        });
    
        function refreshPage(dataURL) {
            if (window.pageData && !pageLoaded) {
                pageLoaded = true;
                loadPage(pageData);
            } else {
                $http.get(dataURL, {
                    headers: spUtil.getHeaders()
                }).success(function(response) {
                    loadPage(response.result);
                });
            }
        }
    
        function isPublicOrUserLoggedIn(page, user) {
            if (page.public)
                return true;
            if (user.user_name == "guest")
                return false;
            return true;
        }
    
        function setCSS(page) {
            jQuery("style[data-page-id='" + page.sys_id + "']").remove();
            if (page.css) {
                var buf = [
                    '<style type="text/css" data-page-id="' + page.sys_id + '" data-page-title="' + page.title + '">',
                    page.css,
                    '</style>'
                ];
                jQuery(jQuery(buf.join('\n'))).appendTo('head');
            }
        }
        $(window).keydown(onKeyDown);
    
        function onKeyDown(e) {
            if (e.keyCode != 83)
                return;
            if (e.metaKey || e.ctrlKey) {
                e.stopPropagation();
                e.preventDefault();
                $rootScope.$broadcast("$sp.save", e);
            }
        }
        $scope.$on('$destroy', function() {
            $(window).off("keydown", onKeyDown);
        })
    });;
    /*! RESOURCE: /scripts/app.$sp/service.spPreference.js */
    angular.module('sn.$sp').factory('spPreference', function(nowServer, $http) {
        "use strict";
        return {
            set: function(name, value) {
                var dataURL = nowServer.getURL("$sp");
                var n = {
                    sysparm_ck: g_ck,
                    type: "set_preference",
                    name: name,
                    value: value
                }
                Object.keys(n).forEach(function(t) {
                    dataURL += "&" + t + "=" + n[t]
                })
                $http.post(dataURL);
            }
        }
    });
    /*! RESOURCE: /scripts/app.$sp/factory.spWidget.js */
    angular.module('sn.$sp').factory('spWidgetService', function($compile, lazyLoader, spServer, $rootScope, $injector) {
        var head = document.head || document.getElementsByTagName('head')[0];
    
        function addElement(options) {
            var el = document.createElement('style');
            el.type = 'text/css';
            if (options.id)
                el.setAttribute('id', options.id);
            if (options.widget)
                el.setAttribute('widget', options.widget);
            if (el.styleSheet)
                el.styleSheet.cssText = options.css;
            else
                el.appendChild(document.createTextNode(options.css));
            return el;
        }
    
        function render(scope, element, template) {
            element.html(template);
            var el = $compile(element.contents())(scope);
            element.replaceWith(el);
        }
    
        function loadCSS(scope) {
            var id = scope.widget.directiveName + '-s';
            if (scope.widget.css) {
                if (scope.widget.update)
                    scope.widget.css = scope.widget.css.replace(new RegExp('v' + scope.widget.sys_id, 'g'), scope.widget.directiveName);
                if (!$("head #" + id).length)
                    head.appendChild(addElement({
                        css: scope.widget.css,
                        id: id,
                        widget: scope.widget.name
                    }));
            }
            if (scope.widget.rectangle && scope.widget.rectangle.css)
                head.appendChild(addElement({
                    css: scope.widget.rectangle.css,
                    widget: scope.widget.name
                }));
        }
    
        function initData(scope) {
            scope.data = scope.widget.data;
            scope.options = scope.widget.options;
            scope.widget_parameters = scope.options;
        }
    
        function noData(scope) {
            if (!scope.widget || !Object.keys(scope.widget).length) {
                return true;
            }
            return false;
        }
    
        function loadDirective(scope, directiveName) {
            if (scope.widget.providers) {
                lazyLoader.providers(scope.widget.providers);
            }
            lazyLoader.directive(directiveName, function($injector) {
                var api = {
                    restrict: 'C',
                    replace: false
                };
                if (typeof scope.data.replace !== 'undefined')
                    api.replace = scope.data.replace;
                if (scope.widget.template)
                    api.template = scope.widget.template;
                if (scope.widget.client_script) {
                    try {
                        eval('api.controller=' + scope.widget.client_script);
                        if (scope.widget.controller_as) {
                            api.controllerAs = scope.widget.controller_as;
                            api.bindToController = {
                                data: '=',
                                options: '=',
                                widget: '=',
                                server: '='
                            };
                        }
                    } catch (e) {
                        console.log(e);
                        console.log(scope.widget.client_script);
                    }
                }
                api.link = function(sc, elem, attr, ctrl) {
                    var link;
                    if (scope.widget.link) {
                        eval('link=' + scope.widget.link);
                        if (link) {
                            link(sc, elem, attr, ctrl)
                        }
                    };
                };
                return api;
            });
        }
    
        function initGlobals(scope) {
            scope.page = scope.page || $rootScope.page;
            scope.portal = $rootScope.portal;
            scope.user = $rootScope.user;
            scope.theme = $rootScope.theme;
            scope.server = spServer.set(scope);
        }
        return {
            render: render,
            loadCSS: loadCSS,
            initData: initData,
            initGlobals: initGlobals,
            noData: noData,
            loadDirective: loadDirective
        }
    });;
    /*! RESOURCE: /scripts/app.$sp/directive.spWidget.js */
    angular.module('sn.$sp').directive('spWidget', function($rootScope, $timeout, lazyLoader, spWidgetService, spUtil) {
        'use strict';
        var service = spWidgetService;
    
        function renderWidget(scope, element) {
            if (scope.widget.ngTemplates)
                lazyLoader.putTemplates(scope.widget.ngTemplates);
            service.initData(scope);
            service.initGlobals(scope);
            var name = scope.widget.sys_id;
            name = "v" + name;
            if (scope.widget.update) {
                name += spUtil.createUid('xxxxx');
            }
            scope.widget.directiveName = name;
            scope.$watch("widget", function(newValue, oldValue) {
                if (newValue !== oldValue)
                    service.initData(scope);
            });
            var idTag = (scope.widget.rectangle_id) ? "id=\"x" + scope.widget.rectangle_id + "\"" : "";
            var template = '<div ' + idTag + ' class="' + name + '" data="data" options="options" widget="widget" server="server"></div>';
            if (name.length == 0)
                return;
    
            function load() {
                service.loadDirective(scope, name, template);
                service.loadCSS(scope);
                service.render(scope, element, template);
            }
            if (scope.widget.dependencies) {
                lazyLoader.dependencies(scope.widget.dependencies).then(load, function(e) {
                    spUtil.format('An error occurred when loading widget dependencies for: {name} ({id}) {error}', {
                        name: scope.widget.name,
                        id: scope.widget.sys_id,
                        error: e
                    });
                    load();
                });
            } else {
                load();
            }
        }
    
        function link(scope, element) {
            if (service.noData(scope)) {
                var w = scope.$watch("widget", function() {
                    if (!service.noData(scope)) {
                        w();
                        renderWidget(scope, element);
                    }
                });
                return;
            }
            renderWidget(scope, element);
        }
        return {
            restrict: "E",
            link: link,
            scope: {
                widget: '=',
                page: '=?'
            }
        };
    });;
    /*! RESOURCE: /scripts/app.$sp/controller.spWidgetDebug.js */
    angular.module('sn.$sp').controller('spWidgetDebug', function($scope, $rootScope, $uibModal, $http, spUtil, $window, i18n) {
        $scope.reveal = false;
        $scope.page = $rootScope.page;
        $scope.portal = $rootScope.portal;
        $scope.contextMenu = function(event) {
            var menu = [];
            if (!event.ctrlKey || !$rootScope.user.can_debug)
                return menu;
            var w = $scope.rectangle.widget;
            var n = "'" + w.name + "'";
            menu.push(n + ' ' + i18n.getMessage('generated in') + ': ' + w._server_time);
            menu.push([i18n.getMessage("Instance Options"), editInstance]);
            menu.push([i18n.getMessage('Instance in Page Editor') + ' ➚', instancePageEdit]);
            menu.push([i18n.getMessage('Page in Designer') + ' ➚', openDesigner]);
            menu.push(null);
            menu.push([i18n.getMessage('Edit Container Background'), editBackground]);
            menu.push(null);
            menu.push([i18n.getMessage('Widget Options Schema'), editOptionSchema]);
            menu.push([i18n.getMessage('Widget in Form Modal'), editWidget]);
            menu.push([i18n.getMessage('Widget in Editor') + ' ➚', openWidgetEditor]);
            menu.push(null);
            menu.push([i18n.getMessage('Log to console') + ': $scope.data', logScopeData]);
            menu.push([i18n.getMessage('Log to console') + ': $scope', logScope]);
            return menu;
        }
    
        function logScope() {
            console.log("Widget $scope.data...", $scope.rectangle.widget);
        }
    
        function logScopeData() {
            console.log("Widget $scope.data...", $scope.rectangle.widget.data);
        }
    
        function editWidget() {
            editRecord('sp_widget', $scope.rectangle.widget.sys_id);
        }
    
        function editInstance() {
            editRecord('sp_instance', $scope.rectangle.sys_id);
        }
    
        function editBackground() {
            editRecord('sp_container', $scope.container.sys_id);
        }
    
        function openDesigner() {
            $window.open('/$spd.do#/' + $scope.portal.url_suffix + '/editor/' + $scope.page.id + '/' + $scope.rectangle.sys_id, '$spd.do');
        }
    
        function openWidgetEditor() {
            openConfig({
                id: 'widget_editor',
                sys_id: $scope.rectangle.widget.sys_id
            });
        }
    
        function instancePageEdit() {
            openConfig({
                id: 'page_edit',
                p: $scope.page.id,
                table: 'sp_instance',
                sys_id: $scope.rectangle.sys_id
            });
        }
    
        function editOptionSchema() {
            var data = {
                embeddedWidgetId: 'we20',
                embeddedWidgetOptions: {
                    sys_id: $scope.rectangle.widget.sys_id
                }
            };
            spUtil.get('widget-modal', data).then(function(widget) {
                widget.options.afterClose = function() {
                    $scope.rectangle.debugModal = null;
                    $rootScope.$broadcast('sp.page.reload');
                };
                $scope.rectangle.debugModal = widget;
            });
        }
    
        function openConfig(params) {
            $window.open('/sp_config?' + $.param(params), 'sp_config');
        }
    
        function editRecord(table, sys_id) {
            var input = {
                table: table,
                sys_id: sys_id
            };
            spUtil.get('widget-options-config', input).then(function(widget) {
                var myModalCtrl = null;
                widget.options.afterClose = function() {
                    $scope.rectangle.debugModal = null;
                };
                widget.options.afterOpen = function(modalCtrl) {
                    myModalCtrl = modalCtrl;
                };
                $scope.rectangle.debugModal = widget;
                var unregister = $scope.$on('sp.form.record.updated', function(evt, fields) {
                    unregister();
                    unregister = null;
                    myModalCtrl.close();
                    $rootScope.$broadcast('sp.page.reload');
                });
            });
        }
    });;
    /*! RESOURCE: /scripts/app.$sp/directive.spNavbarToggle.js */
    angular.module('sn.$sp').directive('spNavbarToggle', function(cabrillo, $timeout) {
        return {
            restrict: 'A',
            link: function($scope, element, attrs) {
                $scope.toggleNavMenu = function() {
                    $(element).collapse('toggle');
                }
                if (cabrillo.isNative) {
                    cabrillo.viewLayout.setNavigationBarButtons([{
                        title: 'Menu'
                    }], $scope.toggleNavMenu);
                }
            }
        }
    });
    /*! RESOURCE: /scripts/app.$sp/directive.spAttachmentButton.js */
    angular.module('sn.$sp').directive('spAttachmentButton', function(cabrillo, $rootScope, $timeout) {
        'use strict';
        return {
            restrict: 'E',
            template: function() {
                var inputTemplate;
                if (cabrillo.isNative()) {
                    inputTemplate = '<a href="#" id="attachment_add" ng-click="showAttachOptions()" class="panel-button sp-attachment-add"><span class="glyphicon glyphicon-camera"></span></a>';
                } else {
                    inputTemplate = '<input type="file" style="display: none" multiple="true" ng-file-select="attachmentHandler.onFileSelect($files)" class="sp-attachments-input"/>';
                    inputTemplate += '<a href="javascript:void(0)" id="attachment_add" ng-click="attachmentHandler.openSelector($event)" class="panel-button sp-attachment-add"><span class="glyphicon glyphicon-paperclip"></span></a>';
                }
                return [
                    '<span class="file-upload-input">',
                    inputTemplate,
                    '</span>'
                ].join('');
            },
            controller: function($element, $scope) {
                $scope.attachmentClassNames = 'btn-default attachment-btn btn-primary icon-paperclip icon-camera list-group-btn';
                $scope.showAttachOptions = function() {
                    var handler = $scope.attachmentHandler;
                    cabrillo.attachments.addFile(
                        handler.tableName,
                        handler.tableId,
                        null, {
                            maxWidth: 1000,
                            maxHeight: 1000
                        }
                    ).then(function(data) {
                        handler.getAttachmentList();
                        $rootScope.$broadcast("added_attachment");
                    }, function() {
                        console.log('Failed to attach new file');
                    });
                };
                $scope.$on('attachment_select_files', function(e) {
                    $timeout(function() {
                        $($element).find('.sp-attachments-input').click();
                    });
                });
            }
        }
    });;
    /*! RESOURCE: /scripts/app.$sp/directive.spPageRow.js */
    angular.module('sn.$sp').directive('spPageRow', function($rootScope, $timeout, $compile) {
        return {
            restrict: 'E',
            templateUrl: 'sp_page_row',
            compile: function($tElement) {
                var el = angular.element($tElement[0]);
                var recursiveNode = el.children(".sp-row-content").remove();
                return function(scope, element, attrs) {
                    var newNode = recursiveNode.clone();
                    element.append(newNode);
                    $compile(newNode)(scope);
                };
            },
            replace: false,
            scope: {
                columns: "=",
                container: "=",
                row: '='
            },
            controller: function($scope) {}
        }
    });
    /*! RESOURCE: /scripts/app.$sp/directive.spPanel.js */
    angular.module('sn.$sp').directive('spPanel', function() {
        return {
            restrict: 'E',
            transclude: true,
            replace: true,
            link: function($scope, $element, $attributes, controller, transcludeFn) {
                $scope.widgetParameters = $scope.widget_parameters || $scope.$parent.widget_parameters || {};
                if (!$scope.options)
                    $scope.options = $scope.$eval($attributes.options) || $scope.$parent.options;
                var title;
                try {
                    title = $scope.$eval($attributes.title);
                } catch (e) {
                    title = $attributes.title
                }
                $scope.title = title || $scope.options.title;
                $scope.bodyClass = $scope.$eval($attributes.bodyClass) || "panel-body";
                transcludeFn($scope, function(clone) {
                    var container = $element.find('div.transclude');
                    container.empty();
                    container.append(clone);
                });
            },
            template: '<div class="panel panel-{{options.color}} b">' +
                '<div class="panel-heading"> <h4 class="panel-title">' +
                '<fa ng-if="options.glyph.length" name="{{options.glyph}}" class="m-r-sm" />{{title}}</h4>' +
                '</div>' +
                '<div class="{{bodyClass}} transclude"></div>' +
                '</div>'
        }
    });;
    /*! RESOURCE: /scripts/app.$sp/directive.spModel.js */
    angular.module('sn.$sp').directive('spModel', function($timeout, spUtil, glideFormFactory, glideUserSession, catalogItemFactory, glideFormEnvironmentFactory, catalogGlideFormFactory, spUIActionFactory, glideModalFactory, $uibModal,
        spModal, glideListFactory) {
        'use strict';
        return {
            restrict: 'E',
            templateUrl: 'sp_model.xml',
            replace: true,
            scope: {
                formModel: "=",
                mandatory: '=',
                isInlineForm: '=?'
            },
            controller: function($element, $scope) {
                var g_form;
                var flatFields;
                var isCatalogItem;
                var debounceFieldChange;
                var formModel;
                $scope.$watch('formModel', function(newValue) {
                    if (angular.isDefined(newValue))
                        init();
                });
                $scope.shouldPullRight = function(layout, rightCol) {
                    return layout == "2across" && rightCol;
                };;
    
                function onChange(fieldName, oldValue, newValue) {
                    if (!(fieldName in formModel._fields))
                        return;
                    $timeout.cancel(debounceFieldChange[fieldName]);
                    debounceFieldChange[fieldName] = $timeout(function() {
                        var field = formModel._fields[fieldName];
                        if (isCatalogItem) {
                            if (field._pricing) {
                                setPrices(field, newValue);
                                setBoolean(field, newValue);
                                calcPrice();
                            }
                        }
                        populateMandatory();
                        var p = {
                            field: field,
                            oldValue: oldValue,
                            newValue: newValue
                        };
                        $scope.$emit("field.change", p);
                        $scope.$emit("field.change." + field.name, p);
                    });
                }
    
                function populateMandatory() {
                    var mandatory = [];
                    var field;
                    for (var f in flatFields) {
                        field = flatFields[f];
                        if (typeof field.mandatory_filled == 'undefined')
                            continue;
                        if (field.mandatory_filled())
                            continue;
                        if (field.visible && field.isMandatory())
                            mandatory.push(field);
                    }
                    $scope.mandatory = mandatory;
                    $scope.$emit("variable.mandatory.change");
                }
    
                function uiMessageHandler(g_form, type, message) {
                    switch (type) {
                        case 'infoMessage':
                            spUtil.addInfoMessage(message);
                            break;
                        case 'errorMessage':
                            spUtil.addErrorMessage(message);
                            break;
                        case 'clearMessages':
                            break;
                        default:
                            return false;
                    }
                }
    
                function getFlatFieldsFromView(formModel) {
                    var fields = [],
                        field;
                    var sections = formModel._sections;
                    if (sections != null) {
                        try {
                            var section, col, container, contField;
                            for (var s in sections) {
                                section = sections[s];
                                if (hasVariablePrefix(section.id))
                                    fields.push(formModel._fields[section.id]);
                                for (var c in section.columns) {
                                    col = section.columns[c];
                                    for (var f in col.fields) {
                                        field = col.fields[f];
                                        if (formModel._fields[field.name])
                                            fields.push(formModel._fields[field.name]);
                                        for (var c in field.containers) {
                                            container = field.containers[c];
                                            for (var cont in container.fields) {
                                                contField = container.fields[cont];
                                                if (formModel._fields[contField.name])
                                                    fields.push(formModel._fields[contField.name]);
                                            }
                                        }
                                    }
                                }
                            }
                        } catch (e) {
                            console.error('spModel.getFlatFieldsFromView() - Error getting fields from _sections -> columns -> fields.', e, formModel);
                        }
                    } else {
                        for (var f in formModel._view) {
                            field = formModel._view[f];
                            if (formModel._fields[field.name])
                                fields.push(formModel._fields[field.name]);
                        }
                    }
                    return fields;
                }
    
                function hasCatalogVariable(flatFields) {
                    for (var f in flatFields) {
                        if (flatFields[f].hasOwnProperty('_cat_variable'))
                            return true;
                    }
                    return false
                }
    
                function calcPrice() {
                    var price = 0;
                    var recurring_price = 0;
                    angular.forEach(formModel._fields, function(field) {
                        if (field.price)
                            price += Number(field.price);
                        if (field.recurring_price)
                            recurring_price += Number(field.recurring_price);
                    });
                    var o = {
                        price: price,
                        recurring_price: recurring_price
                    };
                    $scope.$emit("variable.price.change", o);
                }
    
                function setBoolean(field, value) {
                    if (field.type != 'boolean')
                        return;
                    if (value == true || value == 'true') {
                        field.price = field._pricing.price_if_checked;
                        field.recurring_price = field._pricing.rec_price_if_checked;
                    } else
                        field.price = field.recurring_price = 0;
                }
    
                function setPrices(field, value) {
                    if (!field.choices)
                        return;
                    field.choices.forEach(function(c) {
                        if (c.value != value)
                            return;
                        field.price = c.price;
                        field.recurring_price = c.recurring_price;
                    });
                }
                $scope.getGlideForm = function() {
                    return g_form;
                };
    
                function hasVariablePrefix(v) {
                    return v.indexOf("IO:") == 0;
                }
                $scope.getVarID = function(v) {
                    if (hasVariablePrefix(v.name))
                        return v.name.substring(3);
                    return v.name;
                };
    
                function initGlideForm() {
                    var uiActions = spUIActionFactory.create(formModel._ui_actions || [], {
                        attachmentGUID: formModel._attachmentGUID,
                        uiActionNotifier: function(actionName, uiActionPromise) {
                            uiActionPromise.then(function(response) {
                                $scope.$emit("spModel.uiActionComplete", response);
                            });
                        }
                    });
                    g_form = glideFormFactory.create($scope, formModel.table, formModel.sys_id, flatFields, uiActions, {
                        uiMessageHandler: uiMessageHandler,
                        relatedLists: formModel._related_lists,
                        sections: formModel._sections
                    });
                    g_form.getControl = getControl;
                    g_form.getField = function(fieldName) {
                        for (var i = 0, iM = flatFields.length; i < iM; i++) {
                            var field = flatFields[i];
                            if (field.variable_name === fieldName || field.name === fieldName) {
                                return field;
                            }
                        }
                        if (g_form._options.getMappedField) {
                            var mapped = g_form._options.getMappedField(fieldName);
                            if (mapped) {
                                return mapped;
                            }
                        }
                    };
                    g_form.showFieldMsg0 = g_form.showFieldMsg;
                    g_form.showFieldMsg = function() {
                        g_form.showFieldMsg0.apply(this, arguments);
                        if (!$scope.$root.$$phase) {
                            $scope.$apply();
                        }
                    };
                    g_form.$private.events.on('change', onChange);
                    g_form.$private.events.on('propertyChange', function(type, fieldName, propertyName) {
                        if (propertyName == "mandatory")
                            populateMandatory();
                        if (isCatalogItem && propertyName == "visible")
                            setSectionDisplay(fieldName);
                    });
                    $scope.$on("sp.spFormField.stagedValueChange", function() {
                        populateMandatory();
                    });
                }
    
                function setSectionDisplay(v) {
                    for (var s in formModel._sections) {
                        if (formModel._sections[s].id == v) {
                            $scope.$evalAsync(function() {
                                formModel._sections[s].visible = formModel._fields[v].visible;
                            });
                            return;
                        }
                    }
                }
    
                function massageView() {
                    if (formModel._sections == null) {
                        formModel._sections = [{
                            _bootstrap_cells: 12,
                            visible: true,
                            columns: [{
                                fields: formModel._view
                            }]
                        }];
                    }
                    var section, col, field;
                    for (var s in formModel._sections) {
                        section = formModel._sections[s];
                        for (var c in section.columns) {
                            col = section.columns[c];
                            for (var f in col.fields) {
                                field = col.fields[f];
                                if (field.type == 'field' && !formModel._fields[field.name])
                                    col.fields.splice(f, 1);
                            }
                            if (col.fields.length == 0)
                                section.columns.splice(c, 1);
                        }
                        if (section.columns.length == 0) {
                            formModel._sections.splice(s, 1);
                        }
                    }
                }
    
                function init() {
                    $scope.mandatory = [];
                    debounceFieldChange = {};
                    formModel = $scope.formModel;
                    flatFields = getFlatFieldsFromView(formModel);
                    isCatalogItem = hasCatalogVariable(flatFields);
                    massageView();
                    initGlideForm();
                }
                $scope.execItemScripts = function() {
                    $scope.$emit("spModel.fields.rendered");
                    $timeout(function() {
                        glideUserSession.loadCurrentUser().then(onUserLoad);
                    });
    
                    function onUserLoad(user) {
                        populateMandatory();
                        var g_modal = glideModalFactory.create({
                            alert: modalAlert,
                            confirm: modalConfirm
                        });
                        var gfConfig = glideFormEnvironmentFactory.createWithConfiguration(g_form, user, formModel.g_scratchpad, formModel.client_script || [], formModel.policy || [], g_modal);
                        if (isCatalogItem) {
                            gfConfig.g_env.registerExtensionPoint('g_service_catalog', {
                                'isOrderGuide': function() {
                                    return formModel.isOrderGuideItem;
                                }
                            });
                            catalogGlideFormFactory.addItemEditor(g_form, formModel.sys_id, null, formModel.sys_id, flatFields);
                            calcPrice();
                        }
                        gfConfig.g_env.registerExtensionPoint('spModal', spModal);
                        gfConfig.g_env.registerExtensionPoint('g_list', glideListFactory.init(g_form, flatFields));
                        gfConfig.initialize();
                        $scope.$emit("spModel.gForm.initialized", g_form);
                    }
                };
                $scope.$on('$destroy', function() {
                    if (g_form)
                        $scope.$emit("spModel.gForm.destroyed", formModel.sys_id);
                });
    
                function modalAlert(title, message, done) {
                    spModal.alert(message).then(done);
                }
    
                function modalConfirm(title, message, done) {
                    spModal.confirm(message).then(
                        function() {
                            done(true)
                        },
                        function() {
                            done(false)
                        }
                    );
                }
            }
        }
    
        function getControl(name) {
            var names = this.getFieldNames();
            if (names.indexOf(name) == -1)
                return null;
            return new GlideFormControl(this, name);
    
            function GlideFormControl(g_form, name) {
                this.g_form = g_form;
                this.name = name;
                this.options = [];
                this.focus = function focus() {
                    console.log(">> focus not implemented for " + this.name)
                }
                Object.defineProperty(this, 'value', {
                    get: function() {
                        return this.g_form.getValue(this.name);
                    },
                    set: function(val) {
                        this.g_form.setValue(this.name, val);
                    }
                })
            }
        }
    });;
    /*! RESOURCE: /scripts/app.$sp/service.spCodeEditorAutocomplete.js */
    angular.module('sn.$sp').factory('spCodeEditorAutocomplete', ['$rootScope', '$q', '$http', function($rootScope, $q, $http) {
        'use strict';
        var configCache = {};
        var codeEditorAutocompleteAPI = "/api/now/sp/editor/autocomplete";
        return {
            getConfig: function(tableName, field) {
                if (configCache[tableName + "." + field])
                    return $q.when(configCache[tableName + "." + field]);
                return $http.get(codeEditorAutocompleteAPI + "/table/" + tableName + "/field/" + field).then(function(response) {
                    var responseConfig = response.data.result;
                    configCache[tableName + "." + field] = responseConfig;
                    return responseConfig;
                });
            }
        };
    }]);;
    /*! RESOURCE: /scripts/app.$sp/provider.defaultJSAutocomplete.js */
    angular.module('sn.$sp').provider('defaultJSAutocomplete', function defaultJSAutocompleteProvider() {
        "use strict";
        this.$get = function defaultJSAutocompleteFactory() {
            return {
                "!name": "ecma5",
                "!define": {
                    "Error.prototype": "Error.prototype"
                },
                "Infinity": {
                    "!type": "number",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Infinity",
                    "!doc": "A numeric value representing infinity."
                },
                "undefined": {
                    "!type": "?",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/undefined",
                    "!doc": "The value undefined."
                },
                "NaN": {
                    "!type": "number",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/NaN",
                    "!doc": "A value representing Not-A-Number."
                },
                "Object": {
                    "!type": "fn()",
                    "getPrototypeOf": {
                        "!type": "fn(obj: ?) -> ?",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/getPrototypeOf",
                        "!doc": "Returns the prototype (i.e. the internal prototype) of the specified object."
                    },
                    "create": {
                        "!type": "fn(proto: ?) -> !custom:Object_create",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create",
                        "!doc": "Creates a new object with the specified prototype object and properties."
                    },
                    "defineProperty": {
                        "!type": "fn(obj: ?, prop: string, desc: ?) -> !custom:Object_defineProperty",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty",
                        "!doc": "Defines a new property directly on an object, or modifies an existing property on an object, and returns the object. If you want to see how to use the Object.defineProperty method with a binary-flags-like syntax, see this article."
                    },
                    "defineProperties": {
                        "!type": "fn(obj: ?, props: ?) -> !custom:Object_defineProperties",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty",
                        "!doc": "Defines a new property directly on an object, or modifies an existing property on an object, and returns the object. If you want to see how to use the Object.defineProperty method with a binary-flags-like syntax, see this article."
                    },
                    "getOwnPropertyDescriptor": {
                        "!type": "fn(obj: ?, prop: string) -> ?",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor",
                        "!doc": "Returns a property descriptor for an own property (that is, one directly present on an object, not present by dint of being along an object's prototype chain) of a given object."
                    },
                    "keys": {
                        "!type": "fn(obj: ?) -> [string]",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys",
                        "!doc": "Returns an array of a given object's own enumerable properties, in the same order as that provided by a for-in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well)."
                    },
                    "getOwnPropertyNames": {
                        "!type": "fn(obj: ?) -> [string]",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames",
                        "!doc": "Returns an array of all properties (enumerable or not) found directly upon a given object."
                    },
                    "seal": {
                        "!type": "fn(obj: ?)",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/seal",
                        "!doc": "Seals an object, preventing new properties from being added to it and marking all existing properties as non-configurable. Values of present properties can still be changed as long as they are writable."
                    },
                    "isSealed": {
                        "!type": "fn(obj: ?) -> bool",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/isSealed",
                        "!doc": "Determine if an object is sealed."
                    },
                    "freeze": {
                        "!type": "fn(obj: ?) -> !0",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/freeze",
                        "!doc": "Freezes an object: that is, prevents new properties from being added to it; prevents existing properties from being removed; and prevents existing properties, or their enumerability, configurability, or writability, from being changed. In essence the object is made effectively immutable. The method returns the object being frozen."
                    },
                    "isFrozen": {
                        "!type": "fn(obj: ?) -> bool",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/isFrozen",
                        "!doc": "Determine if an object is frozen."
                    },
                    "preventExtensions": {
                        "!type": "fn(obj: ?)",
                        "!url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions",
                        "!doc": "Prevents new properties from ever being added to an object."
                    },
                    "isExtensible": {
                        "!type": "fn(obj: ?) -> bool",
                        "!url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible",
                        "!doc": "The Object.isExtensible() method determines if an object is extensible (whether it can have new properties added to it)."
                    },
                    "prototype": {
                        "!stdProto": "Object",
                        "toString": {
                            "!type": "fn() -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/toString",
                            "!doc": "Returns a string representing the object."
                        },
                        "toLocaleString": {
                            "!type": "fn() -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/toLocaleString",
                            "!doc": "Returns a string representing the object. This method is meant to be overriden by derived objects for locale-specific purposes."
                        },
                        "valueOf": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/valueOf",
                            "!doc": "Returns the primitive value of the specified object"
                        },
                        "hasOwnProperty": {
                            "!type": "fn(prop: string) -> bool",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/hasOwnProperty",
                            "!doc": "Returns a boolean indicating whether the object has the specified property."
                        },
                        "propertyIsEnumerable": {
                            "!type": "fn(prop: string) -> bool",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable",
                            "!doc": "Returns a Boolean indicating whether the specified property is enumerable."
                        },
                        "isPrototypeOf": {
                            "!type": "fn(obj: ?) -> bool",
                            "!url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isPrototypeOf",
                            "!doc": "Tests for an object in another object's prototype chain."
                        }
                    },
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object",
                    "!doc": "Creates an object wrapper."
                },
                "Function": {
                    "!type": "fn(body: string) -> fn()",
                    "prototype": {
                        "!stdProto": "Function",
                        "apply": {
                            "!type": "fn(this: ?, args: [?])",
                            "!effects": [
                                "call and return !this this=!0 !1.<i> !1.<i> !1.<i>"
                            ],
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply",
                            "!doc": "Calls a function with a given this value and arguments provided as an array (or an array like object)."
                        },
                        "call": {
                            "!type": "fn(this: ?, args?: ?) -> !this.!ret",
                            "!effects": [
                                "call and return !this this=!0 !1 !2 !3 !4"
                            ],
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/call",
                            "!doc": "Calls a function with a given this value and arguments provided individually."
                        },
                        "bind": {
                            "!type": "fn(this: ?, args?: ?) -> !custom:Function_bind",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind",
                            "!doc": "Creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function was called."
                        },
                        "prototype": "?"
                    },
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function",
                    "!doc": "Every function in JavaScript is actually a Function object."
                },
                "Array": {
                    "!type": "fn(size: number) -> !custom:Array_ctor",
                    "isArray": {
                        "!type": "fn(value: ?) -> bool",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/isArray",
                        "!doc": "Returns true if an object is an array, false if it is not."
                    },
                    "prototype": {
                        "!stdProto": "Array",
                        "length": {
                            "!type": "number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/length",
                            "!doc": "An unsigned, 32-bit integer that specifies the number of elements in an array."
                        },
                        "concat": {
                            "!type": "fn(other: [?]) -> !this",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/concat",
                            "!doc": "Returns a new array comprised of this array joined with other array(s) and/or value(s)."
                        },
                        "join": {
                            "!type": "fn(separator?: string) -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/join",
                            "!doc": "Joins all elements of an array into a string."
                        },
                        "splice": {
                            "!type": "fn(pos: number, amount: number, newelt?: ?) -> [?]",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/splice",
                            "!doc": "Changes the content of an array, adding new elements while removing old elements."
                        },
                        "pop": {
                            "!type": "fn() -> !this.<i>",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/pop",
                            "!doc": "Removes the last element from an array and returns that element."
                        },
                        "push": {
                            "!type": "fn(newelt: ?) -> number",
                            "!effects": [
                                "propagate !0 !this.<i>"
                            ],
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/push",
                            "!doc": "Mutates an array by appending the given elements and returning the new length of the array."
                        },
                        "shift": {
                            "!type": "fn() -> !this.<i>",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/shift",
                            "!doc": "Removes the first element from an array and returns that element. This method changes the length of the array."
                        },
                        "unshift": {
                            "!type": "fn(newelt: ?) -> number",
                            "!effects": [
                                "propagate !0 !this.<i>"
                            ],
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/unshift",
                            "!doc": "Adds one or more elements to the beginning of an array and returns the new length of the array."
                        },
                        "slice": {
                            "!type": "fn(from?: number, to?: number) -> !this",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/slice",
                            "!doc": "Returns a shallow copy of a portion of an array."
                        },
                        "reverse": {
                            "!type": "fn()",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/reverse",
                            "!doc": "Reverses an array in place.  The first array element becomes the last and the last becomes the first."
                        },
                        "sort": {
                            "!type": "fn(compare?: fn(a: ?, b: ?) -> number)",
                            "!effects": [
                                "call !0 !this.<i> !this.<i>"
                            ],
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/sort",
                            "!doc": "Sorts the elements of an array in place and returns the array."
                        },
                        "indexOf": {
                            "!type": "fn(elt: ?, from?: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf",
                            "!doc": "Returns the first index at which a given element can be found in the array, or -1 if it is not present."
                        },
                        "lastIndexOf": {
                            "!type": "fn(elt: ?, from?: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/lastIndexOf",
                            "!doc": "Returns the last index at which a given element can be found in the array, or -1 if it is not present. The array is searched backwards, starting at fromIndex."
                        },
                        "every": {
                            "!type": "fn(test: fn(elt: ?, i: number, array: +Array) -> bool, context?: ?) -> bool",
                            "!effects": [
                                "call !0 this=!1 !this.<i> number !this"
                            ],
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/every",
                            "!doc": "Tests whether all elements in the array pass the test implemented by the provided function."
                        },
                        "some": {
                            "!type": "fn(test: fn(elt: ?, i: number, array: +Array) -> bool, context?: ?) -> bool",
                            "!effects": [
                                "call !0 this=!1 !this.<i> number !this"
                            ],
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/some",
                            "!doc": "Tests whether some element in the array passes the test implemented by the provided function."
                        },
                        "filter": {
                            "!type": "fn(test: fn(elt: ?, i: number, array: +Array) -> bool, context?: ?) -> !this",
                            "!effects": [
                                "call !0 this=!1 !this.<i> number !this"
                            ],
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter",
                            "!doc": "Creates a new array with all elements that pass the test implemented by the provided function."
                        },
                        "forEach": {
                            "!type": "fn(f: fn(elt: ?, i: number, array: +Array), context?: ?)",
                            "!effects": [
                                "call !0 this=!1 !this.<i> number !this"
                            ],
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach",
                            "!doc": "Executes a provided function once per array element."
                        },
                        "map": {
                            "!type": "fn(f: fn(elt: ?, i: number, array: +Array) -> ?, context?: ?) -> [!0.!ret]",
                            "!effects": [
                                "call !0 this=!1 !this.<i> number !this"
                            ],
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/map",
                            "!doc": "Creates a new array with the results of calling a provided function on every element in this array."
                        },
                        "reduce": {
                            "!type": "fn(combine: fn(sum: ?, elt: ?, i: number, array: +Array) -> ?, init?: ?) -> !0.!ret",
                            "!effects": [
                                "call !0 !1 !this.<i> number !this"
                            ],
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/Reduce",
                            "!doc": "Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value."
                        },
                        "reduceRight": {
                            "!type": "fn(combine: fn(sum: ?, elt: ?, i: number, array: +Array) -> ?, init?: ?) -> !0.!ret",
                            "!effects": [
                                "call !0 !1 !this.<i> number !this"
                            ],
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/ReduceRight",
                            "!doc": "Apply a function simultaneously against two values of the array (from right-to-left) as to reduce it to a single value."
                        }
                    },
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array",
                    "!doc": "The JavaScript Array global object is a constructor for arrays, which are high-level, list-like objects."
                },
                "String": {
                    "!type": "fn(value: ?) -> string",
                    "fromCharCode": {
                        "!type": "fn(code: number) -> string",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/fromCharCode",
                        "!doc": "Returns a string created by using the specified sequence of Unicode values."
                    },
                    "prototype": {
                        "!stdProto": "String",
                        "length": {
                            "!type": "number",
                            "!url": "https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/String/length",
                            "!doc": "Represents the length of a string."
                        },
                        "<i>": "string",
                        "charAt": {
                            "!type": "fn(i: number) -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/charAt",
                            "!doc": "Returns the specified character from a string."
                        },
                        "charCodeAt": {
                            "!type": "fn(i: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/charCodeAt",
                            "!doc": "Returns the numeric Unicode value of the character at the given index (except for unicode codepoints > 0x10000)."
                        },
                        "indexOf": {
                            "!type": "fn(char: string, from?: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/indexOf",
                            "!doc": "Returns the index within the calling String object of the first occurrence of the specified value, starting the search at fromIndex,\nreturns -1 if the value is not found."
                        },
                        "lastIndexOf": {
                            "!type": "fn(char: string, from?: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/lastIndexOf",
                            "!doc": "Returns the index within the calling String object of the last occurrence of the specified value, or -1 if not found. The calling string is searched backward, starting at fromIndex."
                        },
                        "substring": {
                            "!type": "fn(from: number, to?: number) -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/substring",
                            "!doc": "Returns a subset of a string between one index and another, or through the end of the string."
                        },
                        "substr": {
                            "!type": "fn(from: number, length?: number) -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/substr",
                            "!doc": "Returns the characters in a string beginning at the specified location through the specified number of characters."
                        },
                        "slice": {
                            "!type": "fn(from: number, to?: number) -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/slice",
                            "!doc": "Extracts a section of a string and returns a new string."
                        },
                        "trim": {
                            "!type": "fn() -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/Trim",
                            "!doc": "Removes whitespace from both ends of the string."
                        },
                        "toUpperCase": {
                            "!type": "fn() -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toUpperCase",
                            "!doc": "Returns the calling string value converted to uppercase."
                        },
                        "toLowerCase": {
                            "!type": "fn() -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toLowerCase",
                            "!doc": "Returns the calling string value converted to lowercase."
                        },
                        "toLocaleUpperCase": {
                            "!type": "fn() -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase",
                            "!doc": "Returns the calling string value converted to upper case, according to any locale-specific case mappings."
                        },
                        "toLocaleLowerCase": {
                            "!type": "fn() -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase",
                            "!doc": "Returns the calling string value converted to lower case, according to any locale-specific case mappings."
                        },
                        "split": {
                            "!type": "fn(pattern?: string|+RegExp, limit?: number) -> [string]",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/split",
                            "!doc": "Splits a String object into an array of strings by separating the string into substrings."
                        },
                        "concat": {
                            "!type": "fn(other: string) -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/concat",
                            "!doc": "Combines the text of two or more strings and returns a new string."
                        },
                        "localeCompare": {
                            "!type": "fn(other: string) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/localeCompare",
                            "!doc": "Returns a number indicating whether a reference string comes before or after or is the same as the given string in sort order."
                        },
                        "match": {
                            "!type": "fn(pattern: +RegExp) -> [string]",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/match",
                            "!doc": "Used to retrieve the matches when matching a string against a regular expression."
                        },
                        "replace": {
                            "!type": "fn(pattern: string|+RegExp, replacement: string) -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/replace",
                            "!doc": "Returns a new string with some or all matches of a pattern replaced by a replacement.  The pattern can be a string or a RegExp, and the replacement can be a string or a function to be called for each match."
                        },
                        "search": {
                            "!type": "fn(pattern: +RegExp) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/search",
                            "!doc": "Executes the search for a match between a regular expression and this String object."
                        }
                    },
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String",
                    "!doc": "The String global object is a constructor for strings, or a sequence of characters."
                },
                "Number": {
                    "!type": "fn(value: ?) -> number",
                    "MAX_VALUE": {
                        "!type": "number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/MAX_VALUE",
                        "!doc": "The maximum numeric value representable in JavaScript."
                    },
                    "MIN_VALUE": {
                        "!type": "number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/MIN_VALUE",
                        "!doc": "The smallest positive numeric value representable in JavaScript."
                    },
                    "POSITIVE_INFINITY": {
                        "!type": "number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/POSITIVE_INFINITY",
                        "!doc": "A value representing the positive Infinity value."
                    },
                    "NEGATIVE_INFINITY": {
                        "!type": "number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/NEGATIVE_INFINITY",
                        "!doc": "A value representing the negative Infinity value."
                    },
                    "prototype": {
                        "!stdProto": "Number",
                        "toString": {
                            "!type": "fn(radix?: number) -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/toString",
                            "!doc": "Returns a string representing the specified Number object"
                        },
                        "toFixed": {
                            "!type": "fn(digits: number) -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/toFixed",
                            "!doc": "Formats a number using fixed-point notation"
                        },
                        "toExponential": {
                            "!type": "fn(digits: number) -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/toExponential",
                            "!doc": "Returns a string representing the Number object in exponential notation"
                        },
                        "toPrecision": {
                            "!type": "fn(digits: number) -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/toPrecision",
                            "!doc": "The toPrecision() method returns a string representing the number to the specified precision."
                        }
                    },
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number",
                    "!doc": "The Number JavaScript object is a wrapper object allowing you to work with numerical values. A Number object is created using the Number() constructor."
                },
                "Boolean": {
                    "!type": "fn(value: ?) -> bool",
                    "prototype": {
                        "!stdProto": "Boolean"
                    },
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Boolean",
                    "!doc": "The Boolean object is an object wrapper for a boolean value."
                },
                "RegExp": {
                    "!type": "fn(source: string, flags?: string)",
                    "prototype": {
                        "!stdProto": "RegExp",
                        "exec": {
                            "!type": "fn(input: string) -> [string]",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/exec",
                            "!doc": "Executes a search for a match in a specified string. Returns a result array, or null."
                        },
                        "test": {
                            "!type": "fn(input: string) -> bool",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/test",
                            "!doc": "Executes the search for a match between a regular expression and a specified string. Returns true or false."
                        },
                        "global": {
                            "!type": "bool",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp",
                            "!doc": "Creates a regular expression object for matching text with a pattern."
                        },
                        "ignoreCase": {
                            "!type": "bool",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp",
                            "!doc": "Creates a regular expression object for matching text with a pattern."
                        },
                        "multiline": {
                            "!type": "bool",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/multiline",
                            "!doc": "Reflects whether or not to search in strings across multiple lines.\n"
                        },
                        "source": {
                            "!type": "string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/source",
                            "!doc": "A read-only property that contains the text of the pattern, excluding the forward slashes.\n"
                        },
                        "lastIndex": {
                            "!type": "number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/lastIndex",
                            "!doc": "A read/write integer property that specifies the index at which to start the next match."
                        }
                    },
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp",
                    "!doc": "Creates a regular expression object for matching text with a pattern."
                },
                "Date": {
                    "!type": "fn(ms: number)",
                    "parse": {
                        "!type": "fn(source: string) -> +Date",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/parse",
                        "!doc": "Parses a string representation of a date, and returns the number of milliseconds since January 1, 1970, 00:00:00 UTC."
                    },
                    "UTC": {
                        "!type": "fn(year: number, month: number, date: number, hour?: number, min?: number, sec?: number, ms?: number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/UTC",
                        "!doc": "Accepts the same parameters as the longest form of the constructor, and returns the number of milliseconds in a Date object since January 1, 1970, 00:00:00, universal time."
                    },
                    "now": {
                        "!type": "fn() -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/now",
                        "!doc": "Returns the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC."
                    },
                    "prototype": {
                        "toUTCString": {
                            "!type": "fn() -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toUTCString",
                            "!doc": "Converts a date to a string, using the universal time convention."
                        },
                        "toISOString": {
                            "!type": "fn() -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toISOString",
                            "!doc": "JavaScript provides a direct way to convert a date object into a string in ISO format, the ISO 8601 Extended Format."
                        },
                        "toDateString": {
                            "!type": "fn() -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toDateString",
                            "!doc": "Returns the date portion of a Date object in human readable form in American English."
                        },
                        "toTimeString": {
                            "!type": "fn() -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toTimeString",
                            "!doc": "Returns the time portion of a Date object in human readable form in American English."
                        },
                        "toLocaleDateString": {
                            "!type": "fn() -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toLocaleDateString",
                            "!doc": "Converts a date to a string, returning the \"date\" portion using the operating system's locale's conventions.\n"
                        },
                        "toLocaleTimeString": {
                            "!type": "fn() -> string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString",
                            "!doc": "Converts a date to a string, returning the \"time\" portion using the current locale's conventions."
                        },
                        "getTime": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getTime",
                            "!doc": "Returns the numeric value corresponding to the time for the specified date according to universal time."
                        },
                        "getFullYear": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getFullYear",
                            "!doc": "Returns the year of the specified date according to local time."
                        },
                        "getYear": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getYear",
                            "!doc": "Returns the year in the specified date according to local time."
                        },
                        "getMonth": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getMonth",
                            "!doc": "Returns the month in the specified date according to local time."
                        },
                        "getUTCMonth": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCMonth",
                            "!doc": "Returns the month of the specified date according to universal time.\n"
                        },
                        "getDate": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getDate",
                            "!doc": "Returns the day of the month for the specified date according to local time."
                        },
                        "getUTCDate": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCDate",
                            "!doc": "Returns the day (date) of the month in the specified date according to universal time.\n"
                        },
                        "getDay": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getDay",
                            "!doc": "Returns the day of the week for the specified date according to local time."
                        },
                        "getUTCDay": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCDay",
                            "!doc": "Returns the day of the week in the specified date according to universal time.\n"
                        },
                        "getHours": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getHours",
                            "!doc": "Returns the hour for the specified date according to local time."
                        },
                        "getUTCHours": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCHours",
                            "!doc": "Returns the hours in the specified date according to universal time.\n"
                        },
                        "getMinutes": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getMinutes",
                            "!doc": "Returns the minutes in the specified date according to local time."
                        },
                        "getUTCMinutes": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date",
                            "!doc": "Creates JavaScript Date instances which let you work with dates and times."
                        },
                        "getSeconds": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getSeconds",
                            "!doc": "Returns the seconds in the specified date according to local time."
                        },
                        "getUTCSeconds": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCSeconds",
                            "!doc": "Returns the seconds in the specified date according to universal time.\n"
                        },
                        "getMilliseconds": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getMilliseconds",
                            "!doc": "Returns the milliseconds in the specified date according to local time."
                        },
                        "getUTCMilliseconds": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCMilliseconds",
                            "!doc": "Returns the milliseconds in the specified date according to universal time.\n"
                        },
                        "getTimezoneOffset": {
                            "!type": "fn() -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset",
                            "!doc": "Returns the time-zone offset from UTC, in minutes, for the current locale."
                        },
                        "setTime": {
                            "!type": "fn(date: +Date) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setTime",
                            "!doc": "Sets the Date object to the time represented by a number of milliseconds since January 1, 1970, 00:00:00 UTC.\n"
                        },
                        "setFullYear": {
                            "!type": "fn(year: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setFullYear",
                            "!doc": "Sets the full year for a specified date according to local time.\n"
                        },
                        "setUTCFullYear": {
                            "!type": "fn(year: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCFullYear",
                            "!doc": "Sets the full year for a specified date according to universal time.\n"
                        },
                        "setMonth": {
                            "!type": "fn(month: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setMonth",
                            "!doc": "Set the month for a specified date according to local time."
                        },
                        "setUTCMonth": {
                            "!type": "fn(month: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCMonth",
                            "!doc": "Sets the month for a specified date according to universal time.\n"
                        },
                        "setDate": {
                            "!type": "fn(day: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setDate",
                            "!doc": "Sets the day of the month for a specified date according to local time."
                        },
                        "setUTCDate": {
                            "!type": "fn(day: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCDate",
                            "!doc": "Sets the day of the month for a specified date according to universal time.\n"
                        },
                        "setHours": {
                            "!type": "fn(hour: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setHours",
                            "!doc": "Sets the hours for a specified date according to local time, and returns the number of milliseconds since 1 January 1970 00:00:00 UTC until the time represented by the updated Date instance."
                        },
                        "setUTCHours": {
                            "!type": "fn(hour: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCHours",
                            "!doc": "Sets the hour for a specified date according to universal time.\n"
                        },
                        "setMinutes": {
                            "!type": "fn(min: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setMinutes",
                            "!doc": "Sets the minutes for a specified date according to local time."
                        },
                        "setUTCMinutes": {
                            "!type": "fn(min: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCMinutes",
                            "!doc": "Sets the minutes for a specified date according to universal time.\n"
                        },
                        "setSeconds": {
                            "!type": "fn(sec: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setSeconds",
                            "!doc": "Sets the seconds for a specified date according to local time."
                        },
                        "setUTCSeconds": {
                            "!type": "fn(sec: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCSeconds",
                            "!doc": "Sets the seconds for a specified date according to universal time.\n"
                        },
                        "setMilliseconds": {
                            "!type": "fn(ms: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setMilliseconds",
                            "!doc": "Sets the milliseconds for a specified date according to local time.\n"
                        },
                        "setUTCMilliseconds": {
                            "!type": "fn(ms: number) -> number",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCMilliseconds",
                            "!doc": "Sets the milliseconds for a specified date according to universal time.\n"
                        }
                    },
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date",
                    "!doc": "Creates JavaScript Date instances which let you work with dates and times."
                },
                "Error": {
                    "!type": "fn(message: string)",
                    "prototype": {
                        "name": {
                            "!type": "string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Error/name",
                            "!doc": "A name for the type of error."
                        },
                        "message": {
                            "!type": "string",
                            "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Error/message",
                            "!doc": "A human-readable description of the error."
                        }
                    },
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Error",
                    "!doc": "Creates an error object."
                },
                "SyntaxError": {
                    "!type": "fn(message: string)",
                    "prototype": "Error.prototype",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/SyntaxError",
                    "!doc": "Represents an error when trying to interpret syntactically invalid code."
                },
                "ReferenceError": {
                    "!type": "fn(message: string)",
                    "prototype": "Error.prototype",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/ReferenceError",
                    "!doc": "Represents an error when a non-existent variable is referenced."
                },
                "URIError": {
                    "!type": "fn(message: string)",
                    "prototype": "Error.prototype",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/URIError",
                    "!doc": "Represents an error when a malformed URI is encountered."
                },
                "EvalError": {
                    "!type": "fn(message: string)",
                    "prototype": "Error.prototype",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/EvalError",
                    "!doc": "Represents an error regarding the eval function."
                },
                "RangeError": {
                    "!type": "fn(message: string)",
                    "prototype": "Error.prototype",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RangeError",
                    "!doc": "Represents an error when a number is not within the correct range allowed."
                },
                "TypeError": {
                    "!type": "fn(message: string)",
                    "prototype": "Error.prototype",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/TypeError",
                    "!doc": "Represents an error an error when a value is not of the expected type."
                },
                "parseInt": {
                    "!type": "fn(string: string, radix?: number) -> number",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/parseInt",
                    "!doc": "Parses a string argument and returns an integer of the specified radix or base."
                },
                "parseFloat": {
                    "!type": "fn(string: string) -> number",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/parseFloat",
                    "!doc": "Parses a string argument and returns a floating point number."
                },
                "isNaN": {
                    "!type": "fn(value: number) -> bool",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/isNaN",
                    "!doc": "Determines whether a value is NaN or not. Be careful, this function is broken. You may be interested in ECMAScript 6 Number.isNaN."
                },
                "isFinite": {
                    "!type": "fn(value: number) -> bool",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/isFinite",
                    "!doc": "Determines whether the passed value is a finite number."
                },
                "eval": {
                    "!type": "fn(code: string) -> ?",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/eval",
                    "!doc": "Evaluates JavaScript code represented as a string."
                },
                "encodeURI": {
                    "!type": "fn(uri: string) -> string",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/encodeURI",
                    "!doc": "Encodes a Uniform Resource Identifier (URI) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two \"surrogate\" characters)."
                },
                "encodeURIComponent": {
                    "!type": "fn(uri: string) -> string",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/encodeURIComponent",
                    "!doc": "Encodes a Uniform Resource Identifier (URI) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two \"surrogate\" characters)."
                },
                "decodeURI": {
                    "!type": "fn(uri: string) -> string",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/decodeURI",
                    "!doc": "Decodes a Uniform Resource Identifier (URI) previously created by encodeURI or by a similar routine."
                },
                "decodeURIComponent": {
                    "!type": "fn(uri: string) -> string",
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/decodeURIComponent",
                    "!doc": "Decodes a Uniform Resource Identifier (URI) component previously created by encodeURIComponent or by a similar routine."
                },
                "Math": {
                    "E": {
                        "!type": "number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/E",
                        "!doc": "The base of natural logarithms, e, approximately 2.718."
                    },
                    "LN2": {
                        "!type": "number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/LN2",
                        "!doc": "The natural logarithm of 2, approximately 0.693."
                    },
                    "LN10": {
                        "!type": "number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/LN10",
                        "!doc": "The natural logarithm of 10, approximately 2.302."
                    },
                    "LOG2E": {
                        "!type": "number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/LOG2E",
                        "!doc": "The base 2 logarithm of E (approximately 1.442)."
                    },
                    "LOG10E": {
                        "!type": "number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/LOG10E",
                        "!doc": "The base 10 logarithm of E (approximately 0.434)."
                    },
                    "SQRT1_2": {
                        "!type": "number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/SQRT1_2",
                        "!doc": "The square root of 1/2; equivalently, 1 over the square root of 2, approximately 0.707."
                    },
                    "SQRT2": {
                        "!type": "number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/SQRT2",
                        "!doc": "The square root of 2, approximately 1.414."
                    },
                    "PI": {
                        "!type": "number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/PI",
                        "!doc": "The ratio of the circumference of a circle to its diameter, approximately 3.14159."
                    },
                    "abs": {
                        "!type": "fn(number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/abs",
                        "!doc": "Returns the absolute value of a number."
                    },
                    "cos": {
                        "!type": "fn(number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/cos",
                        "!doc": "Returns the cosine of a number."
                    },
                    "sin": {
                        "!type": "fn(number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/sin",
                        "!doc": "Returns the sine of a number."
                    },
                    "tan": {
                        "!type": "fn(number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/tan",
                        "!doc": "Returns the tangent of a number."
                    },
                    "acos": {
                        "!type": "fn(number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/acos",
                        "!doc": "Returns the arccosine (in radians) of a number."
                    },
                    "asin": {
                        "!type": "fn(number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/asin",
                        "!doc": "Returns the arcsine (in radians) of a number."
                    },
                    "atan": {
                        "!type": "fn(number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/atan",
                        "!doc": "Returns the arctangent (in radians) of a number."
                    },
                    "atan2": {
                        "!type": "fn(y: number, x: number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/atan2",
                        "!doc": "Returns the arctangent of the quotient of its arguments."
                    },
                    "ceil": {
                        "!type": "fn(number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/ceil",
                        "!doc": "Returns the smallest integer greater than or equal to a number."
                    },
                    "floor": {
                        "!type": "fn(number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/floor",
                        "!doc": "Returns the largest integer less than or equal to a number."
                    },
                    "round": {
                        "!type": "fn(number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/round",
                        "!doc": "Returns the value of a number rounded to the nearest integer."
                    },
                    "exp": {
                        "!type": "fn(number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/exp",
                        "!doc": "Returns Ex, where x is the argument, and E is Euler's constant, the base of the natural logarithms."
                    },
                    "log": {
                        "!type": "fn(number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/log",
                        "!doc": "Returns the natural logarithm (base E) of a number."
                    },
                    "sqrt": {
                        "!type": "fn(number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/sqrt",
                        "!doc": "Returns the square root of a number."
                    },
                    "pow": {
                        "!type": "fn(number, number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/pow",
                        "!doc": "Returns base to the exponent power, that is, baseexponent."
                    },
                    "max": {
                        "!type": "fn(number, number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/max",
                        "!doc": "Returns the largest of zero or more numbers."
                    },
                    "min": {
                        "!type": "fn(number, number) -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/min",
                        "!doc": "Returns the smallest of zero or more numbers."
                    },
                    "random": {
                        "!type": "fn() -> number",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/random",
                        "!doc": "Returns a floating-point, pseudo-random number in the range [0, 1) that is, from 0 (inclusive) up to but not including 1 (exclusive), which you can then scale to your desired range."
                    },
                    "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math",
                    "!doc": "A built-in object that has properties and methods for mathematical constants and functions."
                },
                "JSON": {
                    "parse": {
                        "!type": "fn(json: string, reviver?: fn(key: string, value: ?) -> ?) -> ?",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/parse",
                        "!doc": "Parse a string as JSON, optionally transforming the value produced by parsing."
                    },
                    "stringify": {
                        "!type": "fn(value: ?, replacer?: fn(key: string, value: ?) -> ?, space?: string|number) -> string",
                        "!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/stringify",
                        "!doc": "Convert a value to JSON, optionally replacing values if a replacer function is specified, or optionally including only the specified properties if a replacer array is specified."
                    },
                    "!url": "https://developer.mozilla.org/en-US/docs/JSON",
                    "!doc": "JSON (JavaScript Object Notation) is a data-interchange format.  It closely resembles a subset of JavaScript syntax, although it is not a strict subset. (See JSON in the JavaScript Reference for full details.)  It is useful when writing any kind of JavaScript-based application, including websites and browser extensions.  For example, you might store user information in JSON format in a cookie, or you might store extension preferences in JSON in a string-valued browser preference."
                }
            }
        };
    });;
    /*! RESOURCE: /scripts/app.$sp/provider.lazyloader.js */
    angular.module('sn.$sp').provider('lazyLoader', function() {
        "use strict";
        var config = {};
        var propsCache = {};
        var directivesCache = {};
        var promiseCache = {};
        this.set = function(value) {
            config = value;
        };
    
        function directiveExists(name) {
            if (directivesCache[name]) {
                return true;
            }
            directivesCache[name] = true;
            return false;
        }
    
        function isProviderLoaded(provider) {
            if (provider.type === 'directive') {
                return directiveExists(provider.name);
            }
            if (propsCache[provider.name]) {
                return true;
            }
            propsCache[provider.name] = true;
            return false;
        }
        this.$get = ['$controller', '$templateCache', '$window', '$q', '$ocLazyLoad', function($controller, $templateCache, $window, $q, $ocLazyLoad) {
            var head = $window.document.getElementsByTagName('head')[0];
            return {
                directive: config.directive,
                directiveExists: directiveExists,
                controller: config.register,
                putTemplates: function(templates) {
                    for (var i in templates) {
                        $templateCache.put(i, templates[i]);
                    }
                },
                providers: function(provList) {
                    var provider, script;
                    for (var i in provList) {
                        provider = provList[i];
                        if (!isProviderLoaded(provider)) {
                            eval("script=" + provider.script);
                            config[provider.type](provider.name, script);
                        }
                    }
                },
                dependencies: function(depsList) {
                    var deps = depsList.map(function(item) {
                        var files = item.files.map(function(file) {
                            var types = {
                                script: 'js',
                                link: 'css'
                            };
                            return {
                                type: types[file.type],
                                path: file.url
                            }
                        });
                        if (files.length == 1)
                            return files[0];
                        var result = {
                            files: files,
                            serie: true
                        };
                        if (item.module.length > 0)
                            result.module = item.module;
                        return result;
                    });
                    return $ocLazyLoad.load(deps);
                }
            };
        }];
    });;
    /*! RESOURCE: /scripts/app.$sp/factory.spServer.js */
    angular.module('sn.$sp').factory('spServer', function(spUtil) {
        "use strict";
    
        function set(scope) {
            return {
                get: function(data) {
                    return spUtil.get(scope, data);
                },
                update: function() {
                    return spUtil.update(scope);
                },
                refresh: function() {
                    return spUtil.refresh(scope);
                }
            }
        }
        return {
            set: set
        }
    });;
    /*! RESOURCE: /scripts/app.$sp/directive.spOnTransition.js */
    angular.module('sn.$sp').directive('spOnTransition', function($rootScope) {
        function detectEvent() {
            var t, el = document.createElement("test");
            var transitions = {
                "transition": "transitionend",
                "OTransition": "oTransitionEnd",
                "MozTransition": "transitionend",
                "WebkitTransition": "webkitTransitionEnd"
            };
            for (t in transitions) {
                if (el.style[t] !== undefined) {
                    return transitions[t];
                }
            }
        }
        var transition = detectEvent();
        return {
            restrict: 'A',
            scope: {
                spOnTransition: '='
            },
            link: function(scope, element) {
                $(element).on(transition, function() {
                    $rootScope.$broadcast(scope.spOnTransition.event);
                });
            }
        }
    });;
    /*! RESOURCE: /scripts/app.$sp/directive.spContextMenu.js */
    angular.module('sn.$sp').directive('spContextMenu', ["$parse", "$q", function($parse, $q) {
        var contextMenus = [];
        var removeContextMenus = function(level) {
            while (contextMenus.length && (!level || contextMenus.length > level)) {
                contextMenus.pop().remove();
            }
            if (contextMenus.length == 0 && $currentContextMenu) {
                $currentContextMenu.remove();
            }
        };
        var $currentContextMenu = null;
        var renderContextMenu = function($scope, event, options, model, level) {
            if (!level) {
                level = 0;
            }
            if (!$) {
                var $ = angular.element;
            }
            $(event.currentTarget).addClass('context');
            var $contextMenu = $('<div>');
            if ($currentContextMenu) {
                $contextMenu = $currentContextMenu;
            } else {
                $currentContextMenu = $contextMenu;
            }
            $contextMenu.addClass('dropdown clearfix');
            var $ul = $('<ul>');
            $ul.addClass('dropdown-menu');
            $ul.attr({
                'role': 'menu'
            });
            $ul.css({
                display: 'block',
                "padding-top": '0px',
                position: 'absolute',
                left: event.pageX + 'px',
                top: event.pageY + 'px',
                "z-index": 10000
            });
            var $promises = [];
            angular.forEach(options, function(item, i) {
                var $li = $('<li>');
                if (item === null) {
                    $li.addClass('divider');
                } else if (!Array.isArray(item)) {
                    $li.css("padding", "10px 15px");
                    $li.css("background-color", "#eee");
                    $li.css("margin-bottom", "8px");
                    $li.text(item);
                } else {
                    var nestedMenu = angular.isArray(item[1]) ?
                        item[1] : angular.isArray(item[2]) ?
                        item[2] : angular.isArray(item[3]) ?
                        item[3] : null;
                    var $a = $('<a>');
                    $a.css("padding-right", "8px");
                    $a.attr({
                        tabindex: '-1',
                        href: '#'
                    });
                    var text = typeof item[0] == 'string' ? item[0] : item[0].call($scope, $scope, event, model);
                    $promise = $q.when(text)
                    $promises.push($promise);
                    $promise.then(function(text) {
                        $a.text(text);
                        if (nestedMenu) {
                            $a.css("cursor", "default");
                            $a.append($('<strong style="font-family:monospace;font-weight:bold;float:right;">&gt;</strong>'));
                        }
                    });
                    $li.append($a);
                    var enabled = angular.isFunction(item[2]) ? item[2].call($scope, $scope, event, model, text) : true;
                    if (enabled) {
                        var openNestedMenu = function($event) {
                            removeContextMenus(level + 1);
                            var ev = {
                                pageX: event.pageX + $ul[0].offsetWidth - 1,
                                pageY: $ul[0].offsetTop + $li[0].offsetTop - 3
                            };
                            renderContextMenu($scope, ev, nestedMenu, model, level + 1);
                        }
                        $li.on('click', function($event) {
                            $event.preventDefault();
                            $scope.$apply(function() {
                                if (nestedMenu) {
                                    openNestedMenu($event);
                                } else {
                                    $(event.currentTarget).removeClass('context');
                                    removeContextMenus();
                                    item[1].call($scope, $scope, event, model, text);
                                }
                            });
                        });
                        $li.on('mouseover', function($event) {
                            $scope.$apply(function() {
                                if (nestedMenu) {
                                    openNestedMenu($event);
                                }
                            });
                        });
                    } else {
                        $li.on('click', function($event) {
                            $event.preventDefault();
                        });
                        $li.addClass('disabled');
                    }
                }
                $ul.append($li);
            });
            $contextMenu.append($ul);
            var height = Math.max(
                document.body.scrollHeight, document.documentElement.scrollHeight,
                document.body.offsetHeight, document.documentElement.offsetHeight,
                document.body.clientHeight, document.documentElement.clientHeight
            );
            $contextMenu.css({
                width: '100%',
                height: height + 'px',
                position: 'absolute',
                top: 0,
                left: 0,
                zIndex: 9999
            });
            $(document).find('body').append($contextMenu);
            $q.all($promises).then(function() {
                if (level === 0) {
                    var topCoordinate = event.pageY;
                    var menuHeight = angular.element($ul[0]).prop('offsetHeight');
                    var winHeight = event.view.innerHeight;
                    if (topCoordinate > menuHeight && winHeight - topCoordinate < menuHeight) {
                        topCoordinate = event.pageY - menuHeight;
                    }
                    var leftCoordinate = event.pageX;
                    var menuWidth = angular.element($ul[0]).prop('offsetWidth');
                    var winWidth = event.view.innerWidth;
                    if (leftCoordinate > menuWidth && winWidth - leftCoordinate < menuWidth) {
                        leftCoordinate = event.pageX - menuWidth;
                    }
                    $ul.css({
                        display: 'block',
                        position: 'absolute',
                        left: leftCoordinate + 'px',
                        top: topCoordinate + 'px'
                    });
                }
            });
            $contextMenu.on("mousedown", function(e) {
                if ($(e.target).hasClass('dropdown')) {
                    $(event.currentTarget).removeClass('context');
                    removeContextMenus();
                }
            }).on('contextmenu', function(event) {
                $(event.currentTarget).removeClass('context');
                event.preventDefault();
                removeContextMenus(level);
            });
            $scope.$on("$destroy", function() {
                removeContextMenus();
            });
            contextMenus.push($ul);
        };
        return function($scope, element, attrs) {
            element.on('contextmenu', function(event) {
                $scope.$apply(function() {
                    var options = $scope.$eval(attrs.spContextMenu, {
                        event: event
                    });
                    var model = $scope.$eval(attrs.model);
                    if (options instanceof Array) {
                        if (options.length === 0)
                            return;
                        event.stopPropagation();
                        event.preventDefault();
                        renderContextMenu($scope, event, options, model);
                    } else {
                        throw '"' + attrs.contextMenu + '" not an array';
                    }
                });
            });
        };
    }]);;
    /*! RESOURCE: /scripts/app.$sp/filter.spTruncate.js */
    angular.module('sn.$sp')
        .filter('characters', function() {
            return function(input, chars, breakOnWord) {
                if (isNaN(chars)) return input;
                if (chars <= 0) return '';
                if (input && input.length > chars) {
                    input = input.substring(0, chars);
                    if (!breakOnWord) {
                        var lastspace = input.lastIndexOf(' ');
                        if (lastspace !== -1) {
                            input = input.substr(0, lastspace);
                        }
                    } else {
                        while (input.charAt(input.length - 1) === ' ') {
                            input = input.substr(0, input.length - 1);
                        }
                    }
                    return input + '…';
                }
                return input;
            };
        })
        .filter('splitcharacters', function() {
            return function(input, chars) {
                if (isNaN(chars)) return input;
                if (chars <= 0) return '';
                if (input && input.length > chars) {
                    var prefix = input.substring(0, chars / 2);
                    var postfix = input.substring(input.length - chars / 2, input.length);
                    return prefix + '...' + postfix;
                }
                return input;
            };
        })
        .filter('words', function() {
            return function(input, words) {
                if (isNaN(words)) return input;
                if (words <= 0) return '';
                if (input) {
                    var inputWords = input.split(/\s+/);
                    if (inputWords.length > words) {
                        input = inputWords.slice(0, words).join(' ') + '…';
                    }
                }
                return input;
            };
        });;
    /*! RESOURCE: /scripts/app.$sp/factory.spInterceptor.js */
    'use strict';
    angular.module('sn.$sp').factory('spInterceptor', function($q, $rootScope) {
        var activeRequests = [];
        var ignore = [
            '^/api/now/ui/presence'
        ];
    
        function createUid() {
            return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
                var r, v;
                r = Math.random() * 16 | 0;
                v = c === 'x' ? r : r & 0x3 | 0x8;
                return v.toString(16);
            });
        }
    
        function done(id) {
            for (var x in activeRequests) {
                if (activeRequests[x] === id) {
                    activeRequests.splice(x, 1);
                }
            }
            if (activeRequests.length === 0) {
                $rootScope.$broadcast('sp_loading_indicator', false);
                $rootScope.loadingIndicator = false;
            }
        }
    
        function ignored(url) {
            var reg;
            for (var x in ignore) {
                reg = new RegExp(ignore[x]);
                if (reg.test(url)) {
                    return true;
                }
            }
            return false;
        }
    
        function request(config) {
            if (!ignored(config.url)) {
                config.id = createUid();
                activeRequests.push(config.id);
                $rootScope.$broadcast('sp_loading_indicator', true);
                $rootScope.loadingIndicator = true;
            }
            return config;
        }
    
        function error(rejection) {
            if (rejection.config.id) {
                done(rejection.config.id);
            }
            return $q.reject(rejection);
        }
    
        function response(response) {
            if (response.config.id) {
                done(response.config.id);
            }
            return response;
        }
        return {
            request: request,
            requestError: error,
            response: response,
            responseError: error
        };
    });;
    /*! RESOURCE: /scripts/directive.glyph.js */
    angular.module('sn.$sp').directive("glyph", function() {
        "use strict";
        return {
            restrict: 'E',
            replace: true,
            scope: {
                snChar: "@",
            },
            template: '<span class="glyphicon glyphicon-{{snChar}}" />',
            link: function(scope) {}
        }
    });
    /*! RESOURCE: /scripts/app.$sp/directive.spNotifications.js */
    angular.module('sn.$sp').directive('spNotifications', function($timeout) {
        var str = 'CONSOLE:';
    
        function isConsoleMsg(msg) {
            return msg.startsWith(str);
        }
    
        function outputToConsole(msg) {
            var output = msg.substring(str.length);
            var reg = new RegExp("^\\{|^\\[");
            if (reg.test(output)) {
                try {
                    output = jQuery.parseJSON(output);
                } catch (err) {}
            }
            console.warn(output);
        }
        return {
            restrict: 'E',
            replace: true,
            template: '<div id="uiNotificationContainer">\
    <div ng-repeat="m in c.notifications track by $index"\
    class="alert" ng-class="m.type == \'error\' ? \'alert-danger\' : \'alert-success\'">\
    <span ng-bind-html="::m.message"></span>\
    <a ng-if="::$first" class="fa fa-close dismiss-notifications" ng-click="::c.dismissNotifications()"></a>\
    </div>\
    </div>',
            controllerAs: 'c',
            controller: function($scope) {
                var c = this;
                c.notifications = [];
                var timer;
    
                function addNotification(notification) {
                    if (isConsoleMsg(notification.message)) {
                        outputToConsole(notification.message);
                    } else {
                        c.notifications.push(notification);
                        timer = autoDismiss();
                    }
                }
    
                function addNotifications(e, notifications) {
                    if (Array.isArray(notifications)) {
                        for (var x in notifications)
                            addNotification(notifications[x]);
                    } else {
                        addNotification(notifications);
                    }
                }
                $scope.$on("$$uiNotification", addNotifications);
                c.dismissNotifications = function() {
                    c.notifications.length = 0;
                };
                c.getMilliSeconds = function() {
                    var seconds = (areTrivial(c.notifications)) ? 3 : 5;
                    return seconds * 1000;
                };
    
                function areTrivial(input) {
                    return input.length >= 1 && input.every(function(item) {
                        return item && item.type === 'trivial';
                    })
                }
    
                function autoDismiss() {
                    if (timer)
                        $timeout.cancel(timer);
                    return $timeout(c.dismissNotifications, c.getMilliSeconds());
                }
                c.cancelAutoDismiss = function() {
                    if (areTrivial(c.notifications))
                        return;
                    $timeout.cancel(timer);
                };
                $scope.$on("$$uiNotification.dismiss", c.dismissNotifications);
            },
            link: function(scope, element, attrs, ctrl) {
                var $el = $(element);
                $el.on('mouseover', function() {
                    $el.off();
                    ctrl.cancelAutoDismiss();
                });
            }
        }
    });;
    /*! RESOURCE: /scripts/app.$sp/service.spIs.js */
    angular.module('sn.$sp').factory('spIs', function() {
        function email(input) {
            var regex = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
            return regex.test(input);
        }
        return {
            an: {
                email: email
            }
        }
    });;
    /*! RESOURCE: /scripts/app.$sp/service.spThrottle.js */
    angular.module('sn.$sp').factory('spThrottle', ['$timeout', function($timeout) {
        return function(callback, delay) {
            var wait = false;
            return function() {
                if (!wait) {
                    callback.call();
                    wait = true;
                    $timeout(function() {
                        wait = false;
                    }, delay);
                }
            }
        };
    }]);;
    /*! RESOURCE: /scripts/app.$sp/service.spModal.js */
    angular.module('sn.$sp').factory('spModal', function($q, spUtil, $http, $uibModal, i18n) {
        "use strict";
    
        function alert(message) {
            var options = {
                title: message,
                buttons: [{
                    label: i18n.getMessage('OK'),
                    primary: true
                }]
            }
            return alertConfirm(options);
        }
    
        function confirm(message) {
            var options = {
                title: message
            }
            return alertConfirm(options);
        }
    
        function alertConfirm(options) {
            options.messageOnly = true;
            if (options.title.length < 25)
                options.size = 'sm'
            var defer = $q.defer();
            open(options).then(function() {
                defer.resolve(true);
            }, function() {
                defer.reject(false);
            })
            return defer.promise;
        }
    
        function prompt(message, defaultValue) {
            var options = {
                title: message,
                input: true,
                value: defaultValue,
                headerStyle: {
                    border: 'none',
                    'padding-bottom': 0
                },
                footerStyle: {
                    border: 'none',
                    'padding-top': 0
                }
            }
            var defer = $q.defer();
            open(options).then(function(value) {
                defer.resolve(value);
            }, function() {
                defer.reject(null);
            })
            return defer.promise;
        }
    
        function open(options) {
            options = initOptions(options);
            var defer = $q.defer();
            if (options.widget) {
                var widgetURL = spUtil.getWidgetURL(options.widget);
                $http.post(widgetURL, options.widgetInput).success(function(response) {
                    options.widget = response.result;
                    options.widget.options.shared = options.shared;
                    _open(options, defer);
                });
            } else
                _open(options, defer);
            return defer.promise;
        }
    
        function _open(options, defer) {
            $uibModal.open({
                templateUrl: 'sp-modal.html',
                controller: spModalCtrl,
                size: options.size,
                resolve: {
                    options: function() {
                        return options;
                    }
                }
            }).result.then(function(result) {
                if (options.input) {
                    defer.resolve(result.input, result.button);
                } else {
                    defer.resolve(result.button);
                }
            }, function() {
                defer.reject();
            });
        }
    
        function initOptions(options) {
            var defaults = {
                title: '',
                message: '',
                messageOnly: false,
                input: false,
                label: '',
                size: '',
                value: '',
                required: false,
                values: false,
                widget: null,
                widgetInput: null,
                buttons: [{
                        label: i18n.getMessage('Cancel'),
                        cancel: true
                    },
                    {
                        label: i18n.getMessage('OK'),
                        primary: true
                    }
                ]
            };
            options = options || {};
            for (var key in defaults) {
                if (options[key] === undefined) {
                    options[key] = defaults[key];
                }
            }
            if (options.messageOnly) {
                options.headerStyle = {
                    border: 'none'
                }
                options.footerStyle = {
                    border: 'none',
                    'padding-top': 0
                }
            }
            return options;
        }
    
        function spModalCtrl($scope, options, $timeout) {
            $scope.input = {
                value: options.value
            };
            $scope.options = options;
            $scope.form = {};
            if (!options.input) {
                options.buttons.forEach(function(b) {
                    if (b.primary)
                        b.focus = true;
                })
            }
            $scope.buttonClicked = function(button) {
                if (button.cancel) {
                    $scope.$dismiss();
                    return;
                }
                if (options.input && $scope.form.xpForm.$invalid) {
                    $scope.changed = true;
                    return;
                }
                $scope.$close({
                    button: button,
                    input: $scope.input.value
                });
            }
            $scope.submit = function() {
                var ok;
                angular.forEach($scope.options.buttons, function(button) {
                    if (button.primary)
                        ok = button;
                })
                if (ok) $scope.buttonClicked(ok);
            }
        }
        var spModal = {
            alert: alert,
            confirm: confirm,
            prompt: prompt,
            open: open
        };
        return spModal;
    })
    angular.module('sn.$sp').directive('spFocusIf', function focusIf($timeout) {
        function link($scope, $element, $attrs) {
            var dom = $element[0];
            if ($attrs.spFocusIf)
                $scope.$watch($attrs.spFocusIf, focus);
            else
                focus(true);
    
            function focus(condition) {
                if (condition) {
                    $timeout(function() {
                        dom.focus();
                    }, $scope.$eval($attrs.spFocusDelay) || 0);
                }
            }
        }
        return {
            restrict: 'A',
            link: link
        }
    });;
    /*! RESOURCE: /scripts/app.$sp/app.config.js */
    var debug = false;
    angular.module('sn.$sp').config(function(
        $compileProvider,
        $controllerProvider,
        $locationProvider,
        lazyLoaderProvider,
        $provide,
        $httpProvider) {
        $locationProvider.html5Mode({
            enabled: true,
            requireBase: false
        });
        $httpProvider.interceptors.push('spInterceptor');
        lazyLoaderProvider.set({
            register: $controllerProvider.register,
            directive: $compileProvider.directive,
            factory: $provide.factory,
            value: $provide.value,
            service: $provide.service
        });
    });;;